Search code examples
c++winapihwnd

Is it possible to show HWND->i in MessageBox()?


I'm using the following code to get HWND->i but when I start the program it terminates with dialog box "Program.exe has encountered a problem and needs to close":

#include <windows.h>
#include <sstream>

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{
     static TCHAR szAppName[] = TEXT ("Program") ;
     HWND         hwnd ;
     MSG          msg ;
     WNDCLASS     wndclass ;

     wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
     wndclass.lpfnWndProc   = WndProc ;
     wndclass.cbClsExtra    = 0 ;
     wndclass.cbWndExtra    = 0 ;
     wndclass.hInstance     = hInstance ;
     wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
     wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
     wndclass.lpszMenuName  = NULL ;
     wndclass.lpszClassName = szAppName ;

     if (!RegisterClass (&wndclass))
     {
          MessageBox (NULL, TEXT ("Error"), szAppName, MB_ICONERROR) ;
          return 0 ;
     }
     hwnd = CreateWindow (szAppName,
                          TEXT ("Program"),
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT,
                          CW_USEDEFAULT,
                          CW_USEDEFAULT,
                          CW_USEDEFAULT,
                          NULL,
                          NULL,
                          hInstance,
                          NULL) ;

     ShowWindow (hwnd, iCmdShow) ;

     std::ostringstream oss;
     oss << hwnd->i;
     //MessageBox(NULL, oss.str().c_str(), TEXT("message"), MB_OK);

     while (GetMessage (&msg, NULL, 0, 0))
     {
          TranslateMessage (&msg) ;
          DispatchMessage (&msg) ;
     }
     return msg.wParam ;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     switch (message)
     {
     case WM_DESTROY:
          PostQuitMessage (0) ;
          return 0 ;
     }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
}

When I comment out

oss << hwnd->i;

the program runs normally.

So, is there a way to show hwnd->i in MessageBox()?


Solution

  • As it says in MSDN here:

    Windows are objects — they have both code and data — but they are not C++ classes. Instead, a program references a window by using a value called a handle. A handle is an opaque type. Essentially, it is just a number that the operating system uses to identify an object. You can picture Windows as having a big table of all the windows that have been created. It uses this table to look up windows by their handles. (Whether that's exactly how it works internally is not important.) The data type for window handles is HWND, which is usually pronounced "aitch-wind." Window handles are returned by the functions that create windows: CreateWindow and CreateWindowEx.

    And crucially, this comment:

    Keep in mind that handles are not pointers. If hwnd is a variable that contains a handle, attempting to dereference the handle by writing *hwnd is an error.

    The main point is that an HWND is only something you pass along to API calls that deal with windows. Its internal implementation is hidden and is of no concern to developers. By calling HWND->i, you are attempting to dereference it as if it were a pointer, which it's not. Therefore you crash.