-
MessageBox doesnt appear
Hi. Does anyone know why is it that i always have to key "alt" before my MessageBox actually appears? My messagebox is created whenever my button is clicked. I tried making the button control topmost but it didnt work. Here is the code:
Code:
// function to create window
HWND mainFrame::createWindow(HINSTANCE hinst, int nCmdShow, UINT resPoolID, UINT title)
{
HWND hwnd; // handler for window to be created
TCHAR ClassName[MAX_RESOURCESTRING+1]; // window class name
TCHAR wndTitle[MAX_RESOURCESTRING+1]; // window title
HDC hDC;
HBITMAP hBit;
TEXTMETRIC tm;
// load class name into ClassName
LoadString(hinst,resPoolID,ClassName,DIM(ClassName));
// load title name into title
LoadString(hinst,title,wndTitle,DIM(wndTitle));
hwnd = CreateWindowEx(0, // extended window style
ClassName, // class name
wndTitle, // title
WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX, // window style
CW_USEDEFAULT, // default x-pos of window
0, // y-pos of window, set 0 and use showWindow() to determine later
MAX_SCREENWIDTH, // width of window
MAX_SCREENHEIGHT+ GetSystemMetrics(SM_CYMENU)+GetSystemMetrics(SM_CYCAPTION), // height of window
NULL, // parent of window
LoadMenu(hinst, MAKEINTRESOURCE(resPoolID)), // handle of menu
hinst, //handle of application
this); // user defined parameters, hardly any use for it
if(!hwnd)
return NULL;
// make window appear
ShowWindow(hwnd,nCmdShow);
// Create a memory context for window
//----------------------------------------------------//
//1. get display context for window
hDC = GetDC(hwnd);
//2. create compatible memory for window
memDC = CreateCompatibleDC(hDC);
//3. load main bitmap for window
hBit = LoadBitmap(GetWindowInstance(hwnd),MAKEINTRESOURCE(IDB_MAINSCREEN));
//4. select main bitmap into memory DC
//NOTE: MUST NOT DELETE BITMAP WHEN IT IS CURRENTLY SELECTED INTO A DC
hOldBit = (HBITMAP)SelectObject(memDC,hBit);
// 5. delete display context
DeleteDC(hDC);
//----------------------------------------------------//
// ALTERNATE METHOD IS TO USE SAVEDC!!!
// rich edit control for name input
InitCommonControls();
if(!LoadLibrary("riched20.dll"))
return 0;
hDC = GetDC(hEditCtl);
GetTextMetrics(hDC,&tm);
DeleteDC(hDC);
hEditCtl = CreateWindowEx(0,
RICHEDIT_CLASS,
NULL,
WS_CHILD |ES_LEFT| WS_VISIBLE | ES_AUTOHSCROLL | ES_SUNKEN,
177,
284,
22*tm.tmAveCharWidth,
25,
hwnd,
(HMENU)ID_EDIT,
hinst,
NULL);
if(!hEditCtl)
MessageBox(hwnd,"Not working","not working",MB_ICONEXCLAMATION );
// limit the number of character that edit control takes
SendMessage(hEditCtl,EM_EXLIMITTEXT,0,15);
// make edit control beep when max number of character is exceeded
SendMessage(hEditCtl,EM_SETEDITSTYLE,SES_BEEPONMAXTEXT,SES_BEEPONMAXTEXT);
// create default push button
button = CreateWindowEx(0,
_T("button"),
_T("Start"),
WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,
350+15*tm.tmAveCharWidth,
284,
50,
25,
hwnd,
(HMENU)ID_BUTTON,
hinst,
NULL);
// force main window to update
UpdateWindow(hwnd);
return hwnd;
}
void mainFrame::mainWindow_onCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
switch(id)
{case ID_FILE_EXIT: DestroyWindow(hwnd);
return;
case ID_BUTTON: SetWindowPos(hwndCtl,HWND_TOP,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
MessageBox(hwndCtl,"Not working","not working",MB_ICONEXCLAMATION | MB_TOPMOST );
return;
default: FORWARD_WM_COMMAND(hwnd,id,hwndCtl,codeNotify,DefWindowProc);
}
}
-
case ID_BUTTON looks a bit suspect if it's intended to trap button click events; it may be that your MessageBox code is only fired with the 'alt' key due to a coincidence in id values.
Generally, to handle child control notifications check, with respect to your mainWindow_onCommand fn:
- That hwndCtl is a non-NULL value - if it is NULL then the notification (codeNotify) is NOT from a control.
- The value of codeNotify matches the notification you wish to handle. In the case of a button click event, that notification should be BN_CLICKED.
- The value of id is the same as the id for the child control with handle hwndCtl.
This ensures that a particular notification for a specific control is properly handled.
See also WM_COMMAND.
[edit]removed extra 'handled'; I must like that word or something. :rolleyes: [/edit]
-
>>case ID_BUTTON looks a bit suspect if it's intended to trap button click events; it may be that your MessageBox code is only fired with the 'alt' key due to a coincidence in id values.
Actually the messagebox is created correctly, just that i needed to press "alt" to bring it on top of the main window. I am pretty sure i capture the button click events correctly, cos i replaced the code like this and gets the same problem:
Code:
case ID_BUTTON: if(hwndCtl&& (codeNotify == BN_CLICKED))
MessageBox(hwndCtl,"Not working","not working",MB_ICONEXCLAMATION | MB_TOPMOST );
else
FORWARD_WM_COMMAND(hwnd,id,hwndCtl,codeNotify,DefWindowProc);
return;
I still have to pressed "alt" to make the messagebox to bring to foreground and not behind the main window.
However, i noticed if i remove the MoveWindow() statement when handling the WM_PAINT msg. My messagebox will appear correctly. But my edit control will always be painted over by the bitmap in memory DC. I needed the MoveWindow() statement to make sure my edit control appear again after the main window paints its client area.
Code:
void mainFrame::mainWindow_onPaint(HWND hwnd)
{
PAINTSTRUCT ps;
TEXTMETRIC tm;
HDC hDC;
hDC = GetDC(hEditCtl);
GetTextMetrics(hDC,&tm);
DeleteDC(hDC);
// copy the bitmap in memory into display context
hDC = BeginPaint(hwnd,&ps);
BitBlt(hDC,0,0,MAX_SCREENWIDTH,MAX_SCREENHEIGHT,memDC,0,0,SRCCOPY|CAPTUREBLT);
MoveWindow(hEditCtl,177,284,22*tm.tmAveCharWidth,25,TRUE);
UpdateWindow(hEditCtl);
UpdateWindow(button);
EndPaint(hwnd,&ps);
}
-
Ok i managed to solve the problem but it left me with many doubts. Instead of using MoveWindow(), i used SetForegroundWindow():
Code:
void mainFrame::mainWindow_onPaint(HWND hwnd)
{
PAINTSTRUCT ps;
TEXTMETRIC tm;
HDC hDC;
hDC = GetDC(hEditCtl);
GetTextMetrics(hDC,&tm);
DeleteDC(hDC);
// copy the bitmap in memory into display context
hDC = BeginPaint(hwnd,&ps);
BitBlt(hDC,0,0,MAX_SCREENWIDTH,MAX_SCREENHEIGHT,memDC,0,0,SRCCOPY|CAPTUREBLT);
// replaced with SetForegroundWindow()
//MoveWindow(hEditCtl,177,284,22*tm.tmAveCharWidth,25,TRUE);
SetForegroundWindow(hEditCtl);
UpdateWindow(hEditCtl);
UpdateWindow(button);
EndPaint(hwnd,&ps);
}
I have a few questions:
- what changes did MoveWindow() make that my messagebox cannot show up above the main window.
-how come using
Code:
SetWindowPos(hEditCtl,HWND_TOP,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
cannot make my edit control appear like MoveWindow() and SetForegroundWindow() can?
-why does the Bitblt() still paints over my edit control(and yet not the button control) despite i added WS_CLIPCHILDREN to my main window style? I even added CAPTUREBLT to the flag in BitBlt().
FYI, a 24bit bitmap that holds the background of my screen is selected in the memDC for BitBlt()
[EDIT] Argh i posted too soon. When i used SetForegroundWindow() instead, my edit control doesnt update itself when i tried to "backspace" some of the input i typed, unless i minimized it and restore it.
-
A word of caution: when you use GetDC to retrieve a device context handle, use ReleaseDC and not DeleteDC when you're finished with it.
-
yes i corrected that...Thanks.
-
Here is my amended code. I just found out if i hide the edit control before calling the messagebox, the messagebox can appear correctly. But i dont want to hide my edit control. Hope it provide more clues to my problem.
Code:
// function to create window
HWND mainFrame::createWindow(HINSTANCE hinst, int nCmdShow, UINT resPoolID, UINT title)
{
HWND hwnd; // handler for window to be created
TCHAR ClassName[MAX_RESOURCESTRING+1]; // window class name
TCHAR wndTitle[MAX_RESOURCESTRING+1]; // window title
HDC hDC;
HBITMAP hBit;
TEXTMETRIC tm;
// load class name into ClassName
LoadString(hinst,resPoolID,ClassName,DIM(ClassName));
// load title name into title
LoadString(hinst,title,wndTitle,DIM(wndTitle));
hwnd = CreateWindowEx(0, // extended window style
ClassName, // class name
wndTitle, // title
WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX, // window style
CW_USEDEFAULT, // default x-pos of window
0, // y-pos of window, set 0 and use showWindow() to determine later
MAX_SCREENWIDTH, // width of window
MAX_SCREENHEIGHT+ GetSystemMetrics(SM_CYMENU)+GetSystemMetrics(SM_CYCAPTION), // height of window
NULL, // parent of window
LoadMenu(hinst, MAKEINTRESOURCE(resPoolID)), // handle of menu
hinst, //handle of application
this); // user defined parameters, hardly any use for it
if(!hwnd)
return NULL;
// make window appear
ShowWindow(hwnd,nCmdShow);
// Create a memory context for window
//----------------------------------------------------//
//1. get display context for window
hDC = GetDC(hwnd);
GetTextMetrics(hDC,&tm);// get textmetrics for creating window
//2. create compatible memory for window
memDC = CreateCompatibleDC(hDC);
//3. load main bitmap for window
hBit = (HBITMAP) LoadImage(GetWindowInstance(hwnd),
MAKEINTRESOURCE(IDB_MAINSCREEN),
IMAGE_BITMAP,
MAX_SCREENWIDTH,
MAX_SCREENHEIGHT,
LR_CREATEDIBSECTION|LR_VGACOLOR);
//4. select main bitmap into memory DC
//NOTE: MUST NOT DELETE BITMAP WHEN IT IS CURRENTLY SELECTED INTO A DC
hOldBit = (HBITMAP)SelectObject(memDC,hBit);
// 5. delete display context
ReleaseDC(hwnd,hDC);
//----------------------------------------------------//
// ALTERNATE METHOD IS TO USE SAVEDC!!!
// rich edit control for name input
InitCommonControls();
if(!LoadLibrary("riched20.dll"))
return 0;
hEditCtl = CreateWindowEx(0,
RICHEDIT_CLASS,
NULL,
WS_CHILD |ES_LEFT| WS_VISIBLE | WS_CLIPSIBLINGS | ES_AUTOHSCROLL | ES_SUNKEN,
177,
284,
22*tm.tmAveCharWidth,
25,
hwnd,
(HMENU)ID_EDIT,
hinst,
NULL);
if(!hEditCtl)
MessageBox(hwnd,"Not working","not working",MB_ICONEXCLAMATION );
// limit the number of character that edit control takes
SendMessage(hEditCtl,EM_EXLIMITTEXT,0,15);
// make edit control beep when max number of character is exceeded
SendMessage(hEditCtl,EM_SETEDITSTYLE,SES_BEEPONMAXTEXT,SES_BEEPONMAXTEXT);
// create default push button
hButton = CreateWindowEx(0,
_T("button"),
_T("Start"),
WS_CHILD | WS_VISIBLE |WS_CLIPSIBLINGS |BS_DEFPUSHBUTTON,
177 +23*tm.tmAveCharWidth,
284,
50,
25,
hwnd,
(HMENU)ID_BUTTON,
hinst,
NULL);
// force main window to update
UpdateWindow(hwnd);
// set game window's parent window
gf.setParent(hwnd);
return hwnd;
}
Code:
int mainFrame::mainWindow_onPaint(HWND hwnd)
{
PAINTSTRUCT ps;
TEXTMETRIC tm;
HDC hDC;
hDC = GetDC(hEditCtl);
GetTextMetrics(hDC,&tm);
ReleaseDC(hwnd,hDC);
// copy the bitmap in memory into display context
hDC = BeginPaint(hwnd,&ps);
BitBlt(hDC,0,0,MAX_SCREENWIDTH,MAX_SCREENHEIGHT,memDC,0,0,SRCCOPY| CAPTUREBLT);
EndPaint(hwnd,&ps);
MoveWindow(hEditCtl,177,284,22*tm.tmAveCharWidth,25,TRUE);
UpdateWindow(hEditCtl);
UpdateWindow(hButton);
if(hGame)
UpdateWindow(hGame);
return 0;
}
Code:
void mainFrame::mainWindow_onCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
switch(id)
{case ID_FILE_EXIT: DestroyWindow(hwnd);
return;
case ID_BUTTON: if( (hwndCtl == hButton) && (codeNotify == BN_CLICKED) )
{
ShowWindow(hEditCtl,SW_HIDE);
// create the game window, IGNORE THIS FIRST
//gf.createWindow(getHinst(),0,IDR_GAME,0);
MessageBox(hwndCtl,"Not working","not working",MB_ICONEXCLAMATION | MB_TOPMOST | MB_SETFOREGROUND);
}
else
FORWARD_WM_COMMAND(hwnd,id,hwndCtl,codeNotify,DefWindowProc);
break;
default: FORWARD_WM_COMMAND(hwnd,id,hwndCtl,codeNotify,DefWindowProc);
}
}
-
Hi i am taking this chance to bump the thread. Been trying to solve my "edit control not updating and messagebox not appearing" problem for a few days. Really need some help here.
On top of that, i need to know why doesnt my compiler recognize all constants for normal character keys like VK_A,VK_B, etc as an identifier. Isnt it defined somewhere like in winuser.h?
Thanks.
Code:
C:\Documents and Settings\Edmund\My Documents\game and animation\edtris\gameFrame.cpp(436) : error C2065: 'VK_Q' : undeclared identifier
C:\Documents and Settings\Edmund\My Documents\game and animation\edtris\gameFrame.cpp(436) : error C2051: case expression not constant
C:\Documents and Settings\Edmund\My Documents\game and animation\edtris\gameFrame.cpp(437) : error C2065: 'VK_W' : undeclared identifier
C:\Documents and Settings\Edmund\My Documents\game and animation\edtris\gameFrame.cpp(437) : error C2051: case expression not constant
-
Code:
MessageBox(hwndCtl,"Not working","not working",MB_ICONEXCLAMATION | MB_TOPMOST | MB_SETFOREGROUND);
Try using hwnd instead of hwndCtl as the parent window argument to MessageBox.
--
>> On top of that, i need to know why doesnt my compiler recognize all constants for normal character keys like VK_A,VK_B, etc as an identifier. Isnt it defined somewhere like in winuser.h? <<
Just use 'A', 'B', '1', '2', etc. Letters must be uppercase.
-
The problem is with my messagebox and edit control. If i dont call the SetWindowPos() on the edit control in the mainWindow_onPaint function, the messageBox will be able to appear but the edit control cannot update itself.
However, if i have the SetWindowPos() called, the caret in the edit control doesnt blink(it appear just as a non blinking vertical bar) and it can update itself when i typed something. But the messageBox will not appear unless i press "alt". I tried to pass the main window handle, edit window handle, button window handle and NULLto the messageBox. None of it work.
Code:
int mainFrame::mainWindow_onPaint(HWND hwnd)
{
PAINTSTRUCT ps;
TEXTMETRIC tm;
HDC hDC;
hDC = GetDC(hEditCtl);
GetTextMetrics(hDC,&tm);
ReleaseDC(hwnd,hDC);
// copy the bitmap in memory into display context
hDC = BeginPaint(hwnd,&ps);
EndPaint(hwnd,&ps);
//SetWindowPos(hEditCtl,HWND_BOTTOM,177,284,22*tm.tmAveCharWidth,25,SWP_NOZORDER|SWP_NOSIZE|SWP_NOMOVE);
// update controls
UpdateWindow(hEditCtl);
UpdateWindow(hButton);
if(IsWindow(hGame))
UpdateWindow(hGame);
return 0;
}