Thanks - Curt
From Platform SDK documentation:
The WM_INITDIALOG Message
The system does not send a WM_CREATE message to the dialog box procedure.
Instead, it sends a WM_INITDIALOG message when it creates the dialog box and
all its controls but before it displays the dialog box. The procedure should
carry out any initialization required to ensure that the dialog box displays
the current settings associated with the task. For example, when a dialog
box contains a control to show the current drive and directory, the
procedure must determine the current drive and directory and set the control
to that value.
-Mike
I understand what you are saying and I did try the WM_INITDIALOG, however
the WM_INITDIALOG is never called, I've tried. The way I tried was
taking out WM_CREATE and using WM_INITDIALOG with the only thing in it
was a MessageBox function, it didn't work. But when I put the same
MessageBox function in WM_CREATE it worked.
I believe since I defined wndclass.cbWndExtra = DLGWINDOWEXTRA and never
created a regular window that WM_INITDIALOG isn't used. I don't even
use: if (!IsDialogMessage (...)) statement but just the regular message
loop.
The program works, but now I'm trying to add to it and I need the handle
to the edit box.
Curt
could you post a compilable code ?
Thanks - Curt
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK NewEditProc (HWND, UINT, WPARAM, LPARAM);
BOOL GetInput (HWND);
void ConvertRoman (HWND, TCHAR *);
void ConvertArabic (HWND, TCHAR *);
/////
// Global variable
////
WNDPROC g_OldEditFunc;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("Roman");
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = DLGWINDOWEXTRA;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE (ROMANICON));
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
if (!RegisterClass (&wndclass))
return 0;
hwnd = CreateDialog (hInstance, MAKEINTRESOURCE (1001), 0, NULL) ;
ShowWindow (hwnd, iCmdShow);
UpdateWindow (hwnd);
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
static BOOL bFlipFlop = TRUE; // change text on button : TRUE
= "< CONVERT >"
// FALSE = "CLEAR"
HWND hwndEdit;
static char szBuffer[80];
int iNum;
switch (message)
{
case WM_CREATE:
hwndEdit = GetDlgItem(hwnd, ID_ROMAN);
if (hwndEdit)
MessageBox (hwnd, TEXT ("Returned HWND"), TEXT ("HWND"),
MB_OK);
else
{
MessageBox (hwnd, TEXT ("Null value"), TEXT ("NULL"), MB_OK);
iNum = wsprintf (szBuffer, TEXT ("Error = %x"), GetLastError
());
MessageBox (hwnd, szBuffer, TEXT ("ERROR"), MB_OK);
}
g_OldEditFunc = (WNDPROC) SetWindowLong(hwndEdit, GWL_WNDPROC,
(LONG)NewEditProc);
return 0;
case WM_COMMAND:
switch (wParam)
{
case ID_CONVERT:
if ((bFlipFlop) && GetInput (hwnd))
{
SetDlgItemText (hwnd, ID_CONVERT, TEXT ("Clear"));
//SetFocus (hwnd);
bFlipFlop = FALSE;
}
else
{
SetDlgItemText (hwnd, ID_CONVERT, TEXT ("< Convert
>"));
SetDlgItemText (hwnd, ID_ARABIC, TEXT ("\0"));
SetDlgItemText (hwnd, ID_ROMAN, TEXT ("\0"));
//SetFocus (hwnd);
bFlipFlop = TRUE;
}
break;
}
return 0;
case WM_DESTROY:
PostQuitMessage (0);
return 0;
}
return DefWindowProc (hwnd, message, wParam, lParam);
}
> Below is the code. I did not include the NewEditProc function because that
> isn't the problem since I'm not even making it to that function.
You didn't define a Dlg proc and there is no ID_ROMAN in your main window.
ID_ROMAN is defined, it is in an include file, I just didn't include it in
the thread. Because the dialog box is the only window (and thus main
window) WinProc is the only procedure needed.
The program will work fine and compile without errors, however I'm trying
to subclass the edit box and I need the handle to the edit box and for what
ever reason the GetDlgItem isn't returning a handle, it returns NULL.
Thanks - Curt
> ID_ROMAN is defined, it is in an include file, I just didn't include it in
> the thread. Because the dialog box is the only window (and thus main
> window) WinProc is the only procedure needed.
No, there is no ID_ROMAN Edit control in the main window and you mixed
Main window/Dlg proc (you passed NULL for CreateDialog() !)
> ID_ROMAN is defined, it is in an include file, I just didn't include it in
> the thread. Because the dialog box is the only window (and thus main
> window) WinProc is the only procedure needed.
No, there is no ID_ROMAN Edit control in WndProc () (there is no
CreateWindow()) and you mixed Main window/Dlg proc (you passed NULL for
CreateDialog() !)
The WinMain framework for the way this is set up comes exactly from
Petzold's book, Programming Windows, Chapter 11, (HexCalc example). The
program runs but what I'm trying to do is subclass the edit box so that
when enter is pressed when the edit box has focus, it activates a button
click.
Even with the extra code for the subclass, the program still runs, I have 2
edit boxes, one of them is ID_ROMAN.
I'm not trying to be difficult, but I'm obviously missing something. This
was just an experiment in subclassing, which I ended up getting to work
with a different test program.
I appreciate the replies.
Curt.
> The WinMain framework for the way this is set up comes exactly from
> Petzold's book, Programming Windows, Chapter 11, (HexCalc example). The
> program runs but what I'm trying to do is subclass the edit box so that
> when enter is pressed when the edit box has focus, it activates a button
> click.
Because you put NULL in CreateDialog(), then you use the resource window
class.
If you set a standard Dlg procedure, you will get a WM_INITDIALOG message.
Petzold's HexCalc is a very poor example of how to make an application
that uses a dialog as its main window. Because he doesn't need a lot of
the functionality of a dialog, he has eliminated (without telling you
why) a lot of the things that a normal dialog needs.
Petzold's example to the contrary, there is no reason why a normal
dialog (created with DialogBox() ) cannot be the main window of your
program. I've done it many times.
You have written your own window procedure. There is almost never any
reason to do that for a dialog. (The dialog procedure can do almost
everything that is necessary to customize the dialog.) Because you have
a window procedure, you don't get special dialog messages like
WM_INITDIALOG. You do get WM_CREATE but you get it _before_ the child
windows (your controls) are created. That's why GetDlgItem() always
returns NULL. Incidentally, when you write your own window procedure for
a dialog, you need to pass messages to DefDlgProc() instead of
DefWindowProc().
By passing NULL as the last argument to CreateDialog(), you are telling
Windows that you have no dialog procedure. Therefore it never sends
WM_INITDIALOG at all. If you want to get WM_INITDIALOG, you have to have
a dialog procedure.
My recommendation: Use the window procedure that you've written, with a
few modifications, as a dialog procedure. Put its name in as the last
argument to CreateDialog or DialogBox(). Change the WM_CREATE handler to
WM_INITDIALOG. (You will get that message in a dialog procedure and it
will get the handle of the control child window.) Instead of handling
WM_DESTROY, handle WM_COMMAND messages and look for LOWORD(wParam) to be
equal to IDCANCEL. When you get that, call EndDialog() (if you used
DialogBox() ) or DestroyWindow() and PostQuitMessage() (if you used
CreateDialog().) You don't need the WNDCLASS or the call to
RegisterWindow().
--
Norm
To reply, change domain to an adult feline.