11b7 Subj : Re: Unregistered HWND_BROADCAST messages To : borland.public.cpp.borlandcpp From : Ed Mulroy Date : Wed Jun 29 2005 12:10 pm There are problems in that code. - The return values from the RegisterClass and CreateWindow calls are never checked. The code assumes that the window was successfully created. - The calling convention for WndProc is wrong. It uses __cdecl calling convention but should be using __stdcall. The compiler would show a warning about this but it is suppressed by the cast in the assignment of the function's address to the lpfnWndProc element in the WNDCLASS structure. The result is that for each message Windows sends to the function there is a memory leak of about 16 bytes and incorrect information is passed as the calling arguments to DefWindowProc. To correct this, just as is done with WinMain, add WINAPI to the WndProc function header. - What you show does not demonstrate a problem with HWND_BROADCAST. The program cannot know if there is such a problem because it has no message loop. The PM_NOREMOVE given to PeekMessages tell it to not remove messages from the queue. - Code in a PeekMessage loop should detect a WM_QUIT message. When detected the loop should end. If the program has a real message loop (GetMessage - TranslateMessage - DispatchMessage) then it should also recreate the message with a PostQuitMessage(0); call. If the program has no such loop, and this one does not, it should end the program. .. Ed > Alexandre Sá wrote in message > news:42c2a01c@newsgroups.borland.com... > > (sorry if I sent this email widely) > Hi there, the problem I found is: > The unregistered broadcast messages works "fine" on BC++ > and doesn´t work on BCB6 and VC++. > > I´m trying to migrate an old BC++ 4.5 project to the BCB6. > After the migration to BCB6, the unregistered broadcast > messages didn´t work any more. > > But can someone say why it works like that? > Think I need to understand it to be able to > solve the problem I have. > > I put here a fully functional piece of code that reproduce > a different behavior on such compilers. > > Does BC++ 4.5 use a different Windows API (3.1?) to compiler > this code? (even if I create a Win32 project)? > > Any help? > > Best regards, > Alexandre Sá > > PS.: > You know that it´s better register broadcast messages > (RegisterWindowMessage), you know that this code > is not a good programming practice, etc. > But the project was entirely made to use unregistered broadcast > messages and any change may lead to a complete refactoring. > > //----------------------------­­-----------------------------­-­------------ > //---------------------------­­------------------------------­­------------- > //This code creates a window class (WNDCLASS), register the > //class (RegisterClass), creates a window instance (CreateWindow), > //sends a (user defined and unregistered) broadcast message and > tries to > //peek this message (PeekMessage). On BC++, the message is > peeked, and on the //BCB6 (or VC++) it´s not peeked. > > #include > > //---------------------------­­------------------------------­­------------- > static LRESULT WndProc (HWND hWnd, UINT msg, > WPARAM wParam, LPARAM lParam) { > return (DefWindowProc(hWnd,msg,wParam­­,lParam)); > } > > //------------------------­---­---------------------------­--­-------------- > #pragma argsused > WINAPI WinMain(HINSTANCE hInstance, >HINSTANCE hPrevInstance, > LPSTR lpCmdLine, int nCmdShow) > { > WNDCLASS windowClass = {0}; > > windowClass.style = CS_HREDRAW | CS_VREDRAW | > CS_OWNDC ; > windowClass.lpfnWndProc = (WNDPROC)WndProc; > windowClass.cbClsExtra = 0; > windowClass.cbWndExtra = 0; > windowClass.hInstance = hInstance ; > windowClass.hbrBackground = (HBRUSH) > (GetStockObject(BLACK_­­BRUSH)); > windowClass.lpszMenuName = NULL; > windowClass.lpszClassName = "TMyForm"; > > RegisterClass(&windowClass); > > HWND hWindow = CreateWindow ( > "TMyForm", "MyForm", WS_POPUPWINDOW, > 10, 10, 200, 200, > NULL, NULL, > hInstance, NULL); > > PostMessage(HWND_BROADCAST, WM_USER+2, 0, 0L); > MSG m; > while(PeekMessage (&m, NULL, 0, 0, PM_NOREMOVE)) { > if(m.message == (WM_USER+2)) { > MessageBox(NULL, "Work!", "", MB_OK); > } > } > > MessageBox(NULL, "end", "", MB_OK); > return 0; > } . 0