   Win32 cant detect button press
  Hi Guys,I am playing with Parent windows and child windows. All is working as I want except I cant detect the press of IDC_MAIN_BUTTON in the child window.#include<windows.h>#include"resource.h"#define IDC_MAIN_EDITWM_USER+1#define IDC_MAIN_BUTTONWM_USER+2#define IDC_MAIN_BUTTON2WM_USER+3// function prototypesvoid InitApp();LRESULT CALLBACK MainProc(HWND,UINT,WPARAM,LPARAM);LRESULT CALLBACK OtherProc(HWND,UINT,WPARAM,LPARAM);// Global variablesHWND hWnd;HWND other;HMENU hMenu=NULL;// Program entry pointint WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrev,LPSTR line,int CmdShow){hMenu = LoadMenu(hInst,MAKEINTRESOURCE(IDR_MENU1));InitApp();MSG msg;while(GetMessage(&msg,0,0,0)){TranslateMessage(&msg);DispatchMessage(&msg);}return msg.wParam;}// initlize applicationvoid InitApp(){WNDCLASS wc;wc.cbClsExtra = 0;wc.cbWndExtra = 0;wc.hbrBackground = (HBRUSH) GetStockObject(LTGRAY_BRUSH);wc.hInstance = GetModuleHandle(NULL); //hInst;wc.hCursor = LoadCursor(NULL,IDC_ARROW);wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);wc.lpfnWndProc = (WNDPROC) MainProc;wc.lpszClassName = "Main";wc.lpszMenuName = NULL; //(LPCSTR)hMenu;wc.style = CS_HREDRAW | CS_VREDRAW;RegisterClass(&wc);wc.lpszClassName = "Other";wc.lpfnWndProc = (WNDPROC) OtherProc;wc.hbrBackground = (HBRUSH)16;RegisterClass(&wc);hWnd = CreateWindow("Main","Accounting Application",WS_OVERLAPPEDWINDOW,0,0,170,55,0,hMenu,GetModuleHandle(NULL),0);other = CreateWindow("Other","Customer",WS_OVERLAPPEDWINDOW,200,200,640,480,0,0,GetModuleHandle(NULL),0);ShowWindow(hWnd,SW_SHOWMAXIMIZED);UpdateWindow(hWnd);}// Main CallBack FunctionLRESULT CALLBACK MainProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam){switch(msg){case WM_DESTROY:{PostQuitMessage(0);}break;case WM_CREATE:{}break;case WM_COMMAND:{switch(LOWORD(wParam)){case ID_FILE_EXIT:{PostQuitMessage(0);} break;case ID_MASTERFILES_CUSTOMER:{ShowWindow(other,SW_SHOW);} break;}}break;default: return DefWindowProc(hWnd,msg,wParam,lParam);}return 0;}// Other Window CallBack FunctionLRESULT CALLBACK OtherProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam){switch(msg){case WM_CREATE:{HGDIOBJ hfDefault=GetStockObject(DEFAULT_GUI_FONT);HWND hButton=CreateWindowEx(NULL,"BUTTON","OK",WS_TABSTOP|WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON,390,400,100,24,hWnd,(HMENU)IDC_MAIN_BUTTON,GetModuleHandle(NULL),NULL);SendMessage(hButton,WM_SETFONT,(WPARAM)hfDefault,MAKELPARAM(FALSE,0));}break;case WM_CLOSE:{ShowWindow(hWnd,SW_HIDE);}break;case WM_COMMAND:{switch(LOWORD(wParam)){case IDC_MAIN_BUTTON:{MessageBox(NULL,"Button pressed","Information",MB_ICONINFORMATION);}break;}break;}break;default: return DefWindowProc(hWnd,msg,wParam,lParam);}return 0;}This is driving me crazy as I can prove that WM_CREATE and WM_CLOSE work ok in the child window but just cant detect IDC_MAIN_BUTTON.If anyone could help, this would be awesome!Thanks in advance.  :)   
  What an awesome bug! Took me a while to figure out :)Note: That's one of the main reasons #define constants are bad. Your IDC_MAIN_BUTTON is #define IDC_MAIN_BUTTON WM_APP + 2When inserted in the CreateWindowEx line you cast to HMENU:(HMENU)IDC_MAIN_BUTTONNow #defines are inserted literally, this makes it:(HMENU)WM_APP + 2Lovely. WM_APP is cast to HMENU (which itself is a strawman typedef for a pointer to a HMENU__ struct). Now pointer arithmetic kicks in and increases the pointer by two instances of the pointee, namely 8 bytes. That's why in your code wParam contains 0x0408 instead of the 0x0402 you expected.Fix:Either change the define to have paranthesis:#define IDC_MAIN_BUTTON (WM_APP + 2)Or #define a direct value.   ;  Classic! You just beat me to it.I tried changing the defines to a constant number and the application started working. I had no idea, in effect, what the difference was though.Your explanation is awesome! How long did you spend working that out? You have definately gone above and beyond! If I could rate you up 10 times I would. 1 will have to do though, unfortunately.   ;  Was a few steps to get there:First step I did was to stepped into the debugger at the WM_COMMAND handler of the customer dialog. You saw that there was indeed a button press message. It had the wrong ID however (0x0408). At that points I can only recommend the Spy++ tool from MS; should be installed with Visual Studio. It lets you look at all existing windows and their properties (and beyond that). From there on just a little bit of checking where the wrong ID came in.T'was good practise, your code looked correct and yet... ;)A hint maybe: The customer dialog, is it meant to be completely unrelated to the main window? (both show up in the task bar). You could set the customer dialog's parent to the main window to mark it as owner.   ;  Mamoth effort you have put in. Well done!And thanks again.   