How do I get an minimized icon for a dialog box in MFC?
Doran Kangwai -- dkangwai@cch.com.au
Thursday, October 24, 1996
Environment: NT 3.51, VC++ 1.52
I want to use a dialog box as a main window with MFC.
I can do this sucessfully by using:
class CT1Dlg: public CDialog
{
public:
CT1Dlg();
protected:
virtual void PostNcDestroy();
afx_msg void OnQuitClicked();
DECLARE_MESSAGE_MAP()
};
BOOL CT1App::InitInstance()
{
m_pMainWnd = new CT1Dlg;
m_pMainWnd->ShowWindow( m_nCmdShow );
m_pMainWnd->UpdateWindow();
return TRUE;
}
to create the main window and the contructor:
CT1Dlg::CT1Dlg()
{
Create( IDD_T1 );
}
and terminate the app with
void CT1Dlg::OnQuitClicked()
{
TRACE( "In CT1Dlg::OnQuitClicked()\n" );
DestroyWindow();
::PostQuitMessage(0);
}
void CT1Dlg::PostNcDestroy()
{
TRACE( "In CT1Dlg::PostNcDestroy()\n" );
delete this;
}
The problem is that I want the user to be able
to minimize the dialog. Unfortunately I cannot
get the dialog to use MY icon, it just uses
a default white box.
Now I can create a dialog box as a main window
that uses my icon with the WIN 3.1 SDK by using
static char szDlgName[] = "T2DLG";
int __pascal WinMain( HINSTANCE hCurrentInstance,
HINSTANCE hinstPrevious, LPSTR lpszCmdLine, int nCmdShow )
{
HWND hWnd;
MSG msg;
WNDCLASS t2WndClass ;
if ( !hinstPrevious )
{
t2WndClass.style = CS_HREDRAW | CS_VREDRAW;
t2WndClass.lpfnWndProc = t2WndProc;
t2WndClass.cbClsExtra = 0;
t2WndClass.cbWndExtra = DLGWINDOWEXTRA;
t2WndClass.hInstance = hCurrentInstance;
// Use my ICON
t2WndClass.hIcon = LoadIcon( hCurrentInstance, MAKEINTRESOURCE( IDI_T2 ) );
t2WndClass.hCursor = LoadCursor( NULL, IDC_ARROW );
t2WndClass.hbrBackground = COLOR_WINDOW + 1;
t2WndClass.lpszMenuName = NULL;
t2WndClass.lpszClassName = szDlgName;
RegisterClass( &t2WndClass );
} // if
hWnd = CreateDialog( hCurrentInstance, szDlgName, 0, NULL );
...
and
T2DLG DIALOG DISCARDABLE 0, 0, 185, 92
STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX
CLASS "T2DLG"
CAPTION "Test Dialog"
FONT 8, "MS Sans Serif"
BEGIN
PUSHBUTTON "&Quit",IDC_QUIT,125,20,50,14
END
The t2WndClass.cbWndExtra = DLGWINDOWEXTRA;
and
CLASS "T2DLG" seem to be the important bits.
I need to somehow create a WNDCLASS and make
MFC use it to create the dialog box. I tried
overriding PreCreateWindow but it didn't seem
to be called when a dialog is created. I am
looking at CreateIndirect but still cannot
see how to tell MFC to use my WNDCLASS.
Oh how I wish WIN16 had the WIN32
WM_SETICON message so I could use SetIcon()!
Any ideas????
Sorry this turned out longer than I thought
it would but thanks if you got this far.
Doran Kangwai
CCH Australia Limited
Gordon Weakliem -- gweakl@metronet.com
Sunday, October 27, 1996
At 12:13 PM 10/24/96 +1000, you wrote:
>
>Environment: NT 3.51, VC++ 1.52
>
>I want to use a dialog box as a main window with MFC.
>I can do this sucessfully by using:
>
>class CT1Dlg: public CDialog
>{
>public:
> CT1Dlg();
>
>protected:
> virtual void PostNcDestroy();
>
> afx_msg void OnQuitClicked();
> DECLARE_MESSAGE_MAP()
>};
>The problem is that I want the user to be able
>to minimize the dialog. Unfortunately I cannot
>get the dialog to use MY icon, it just uses
>a default white box.
You haven't overriden CDialog::OnPaint(), e.g.
void CT1Dlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
Gordon Weakliem
gweakl@metronet.com
http://www.metronet.com/~gweakl
Dong Chen -- d_chen@ix.netcom.com
Monday, October 28, 1996
[Mini-digest: 4 responses]
I wrote a dialog based application under NT 3.51 a while ago (VC++ 2.x),
what I did was slight different. I loaded the Icon in the constructor. In
OnPaint(), I checked if the app is iconic, if so, I draw the icon. Also, I
used OnQueryDragIcon() to handle the situation when the user drags the
iconic app.
Please post it if you got any better solution.
--
Dong
-----From: Ian Pepper
Hi Doran,
You need to add the following to your ctor
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
where m_hIcon is declared in your class as HICON and handle the WM_PAINT
and WM_QUERYDRAGICON messages thus:
void CT1Dlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM)dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
// Draw the icon
dc.DrawIcon((rect.Width() - cxIcon + 1) / 2, (rect.Height() - cyIcon +
1) / 2, m_hIcon);
}
else
CDialog::OnPaint();
}
HCURSOR CT1Dlg::OnQueryDragIcon()
{
return (HCURSOR)m_hIcon; // use the icon as cursor when dragging
minimized window
}
Ian
ian@flexicom.ie
-----From: tstewa00
Hi Gordon,
I had the same problem a while back. I found the answer on the Stingray MFC
FAQ.
They suggest the following:
// Create your Dialog
m_pMainWnd = new CMainDialog();
#if(_MFC_VER >= 0x0300)
SetClassLong(m_pMainWnd->m_hWnd,GCL_HICON,
(LONG)LoadIcon(IDC_ICONDIALOGAPP)); // Load your icon
#else
SetClassWord(m_pMainWnd->m_hWnd,GCW_HICON,
(WORD)LoadIcon(IDC_ICONDIALOGAPP)); // Load your icon
#endif
m_pMainWnd->ShowWindow(m_nCmdShow);
Short and sweet!
[Moderator's note: Short and sweet, but I think it's wrong. It is
very dangerous to set the icon for a class - all windows in the
class, whether they are part of your thread or not, will get the same
icon.]
-----From: Dave_Rabbers@Quinton-Eng.CCMAIL.CompuServe.COM
Refer to MS knowledge base article Q87976 for sample code.
| Вернуться в корень Архива
|