Thread: How to access a structure from a message handling function

  1. #1
    Registered User
    Join Date
    Jan 2010
    Posts
    206

    Post How to access a structure from a message handling function

    Hi there,

    I would like to use a dialogue box message handling function to add some strings and data to combo boxes. I would also however like to avoid the use of global variables if possible.

    I can access the structs I make inside the message handling function if I declare structs globally but I don't think I should be doing that. What I'd like to do is call a function inside the message procedure that retrieves data from the hardware about rendering capabilities and then adds the strings and corresponding data to items in the combo boxes.

    How would I achieve this without using a global variable. I would really like to just declare a resizable array of structs in the main function and then have the function in the dialogue message handler fill them up with data retrieved from hardware which can then be added to the combo boxes.

    So the function inside the message handler would need access to the array of structs to fill them, and so would the functions that add data to the combo boxes when copying stuff across from the structs.

    I could modify the standard message handler function call to accommodate a pointer to the array but I feel that messing with windows this way is a bad idea.

    I know this all sounds a bit windowsey for the general C++ forum but I felt the majority of concerns are routed in C++ wisdom rather than windows, so I posted it here.

    Could I maybe get around this by just declaring a resizable array (vector from STL) as a static variable inside the main function? Would the message handler be able to access it then?

    Thanks

  2. #2
    Registered User
    Join Date
    Dec 2017
    Posts
    1,633
    A little inaccuracy saves tons of explanation. - H.H. Munro

  3. #3
    Registered User
    Join Date
    Jan 2010
    Posts
    206

    Post Thanks :)

    So far that seems to have worked very nicely John. I started out by declaring a simple struct as a variable type at the top of the .cpp file above the WinMain function:

    Code:
    struct testStruct
    {
        WCHAR name[MAX_STRINGLENGTH];
        int id;
    };
    
    ...sometime later inside the WinMain function
    
    testStruct struct1;
    wcscpy_s(struct1.name, L"Struct_String"); //used the memory safe version of the string copy function
    Then following the instructions on the link you sent me I made the CreateWindowEx function call like this:

    Code:
    HWND hWnd = CreateWindowExW(WS_EX_OVERLAPPEDWINDOW,
                                   szWindowClass,
                                   szTitle,
                                   WS_OVERLAPPEDWINDOW,
                                   CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr, hInstance, &_struct);
    Note the pointer at the end, the last argument. The window now has a pointer to my user made variable. Then inside the window message handler function I did this:

    Code:
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        static testStruct* pStruct;
    
        if (message == WM_CREATE)
        {
            CREATESTRUCT* pCreate = reinterpret_cast<CREATESTRUCT*>(lParam);
    
            pStruct = reinterpret_cast<testStruct*>(pCreate->lpCreateParams);
            SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)pStruct);
        }
    Not sure if the user variable needed to be declared as static but I sure only wanted it to ever be one thing so I declared it as static. AFAIK This now means the pointer has been set correctly, and is accessible outside of this function using the GetWindowLongPtr function.

    Which is what happens below in the message handler for the dialogue box:

    Code:
    // Message handler for about box.
    INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
        LONG_PTR ptr = GetWindowLongPtr(GetParent(hDlg), GWLP_USERDATA);
        static testStruct* pStruct = reinterpret_cast<testStruct*>(ptr);
    And finally the call that adds the string to the combo box entry further down in the dialogue box message handler:

    Code:
    switch (message)
        {
        case WM_INITDIALOG:        
            SendMessage(GetDlgItem(hDlg, IDC_COMBO1), CB_ADDSTRING, NULL, (LPARAM)pStruct->name);
            return (INT_PTR)TRUE;
    Which gives the final result of this testing program:

    How to access a structure from a message handling function-combo-box-1-jpg

    Thanks very much for the link John

    p.s. this has now all got much more windowsey than I first thought it would so perhaps the topic/thread should be moved.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Access vector<structure> elements in a function, how?
    By KeithS in forum C++ Programming
    Replies: 5
    Last Post: 10-25-2011, 10:56 AM
  2. unable to access structure within a function
    By bluetxxth in forum C Programming
    Replies: 7
    Last Post: 02-17-2010, 03:52 AM
  3. Problem in message handling VC++
    By 02mca31 in forum Windows Programming
    Replies: 5
    Last Post: 01-16-2009, 09:22 PM
  4. Message Handling
    By sethjackson in forum Windows Programming
    Replies: 14
    Last Post: 07-11-2006, 01:01 PM
  5. Control message handling
    By Homunculus in forum Windows Programming
    Replies: 5
    Last Post: 02-06-2006, 05:56 PM

Tags for this Thread