Thread: Retrieving lpCreateParams from lParam

  1. #1
    Registered User carrotcake1029's Avatar
    Join Date
    Apr 2008
    Posts
    404

    Retrieving lpCreateParams from lParam

    I am writing a Win32 GUI using API and am coming up with the following problem.

    I basically have a edit control and a button associated with eachother. This means to me that when the button is pushed, it opens an Open Dialog, and then I put the file selected into the edit control.

    What I am trying to do is avoid global variables and see if I can pass data through existing structs. Now in the WndProc callback function, I make a call to SendMessage() which needs the HWND of the edit control.

    So when I create the button control, I try to pass the address of the edit control in the CREATESTRUCT, but am unable to successfully retrieve it later on.

    My code is below, but this seems to be a pain in the ass and if anyone has any suggestions I am all ears.

    Code:
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
        ...
        HWND *edit1 = malloc(sizeof(HWND));
        ...
        temp = CreateWindow(
            "edit",
            "",
            WS_VISIBLE | WS_CHILD | WS_BORDER | ES_AUTOHSCROLL,
            5, 25,
            120, 20, hwnd,
            NULL, hInstance, NULL);
            
        edit1 = &temp;
        
        button1 = CreateWindow(
            "button",
            "Browse...",
            WS_VISIBLE | WS_CHILD,
            130, 25,
            80, 20, hwnd,
            (HMENU)ID_BUTTON1, hInstance, edit1);
            
        ...
    }
    
    LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {    
        CREATESTRUCT *cs;
        HWND *hwnd_t;
        ...
        case WM_COMMAND:
            switch(LOWORD(wParam))
            {
                case ID_BUTTON1:
                {
                    szFile = shell_opendialog(szFile);
                    if (szFile != NULL)
                    {
                        cs = (CREATESTRUCT*)lParam;
                        hwnd_t = (HWND*)cs->lpCreateParams;
                        SendMessage(*hwnd_t, WM_SETTEXT, 0, (LPARAM)szFile); 
                    }
                }
        ...
    }
    Also I may have forgotten some rules about pointers, its been a while for me.

  2. #2
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    No offense is intended but I think you'd do well to revisit your tutorials on windows programming. What you have so far doesn't really show much sign of working.
    Last edited by CommonTater; 10-10-2010 at 06:22 AM.

  3. #3
    Registered User carrotcake1029's Avatar
    Join Date
    Apr 2008
    Posts
    404
    I'm sorry if it comes off this way, but the ellipses are points in which I just trimmed code.

    Everything is functional, its just that I basically need a create way to make variables in WinMain available in WndProc.

    Also, what you suggested is what I am doing, I'm going back and reviewing everything but can't find a simple solution to my problem.

  4. #4
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    To make variables in winman available outside winmain you can define them outside winmain...

    Below is the complete code for an ultra simple unicode editor. Pehaps you can derive some guidance from the way it's built.

    Code:
    /* 
    
    Tiny Unicode Editor Example
    
    */
    // for the compiler
    #define UNICODE
    #define _UNICODE
    #define WIN32_DEFAULT_LIBS
    #define WIN32_LEAN_AND_MEAN
    #define _WIN32_WINNT 0x0502
    #define _X86_
    
    // Windows headers
    #include <windows.h>
    #include <commdlg.h>
    
    //  PellesC headers
    #include <stdlib.h>
    #include <wchar.h>
    
    #define BOM_FLAG 0xFFFE
    
    
    // Window handles
    HWND      Wind[5];  
    HINSTANCE Inst;
    TCHAR     FileName[MAX_PATH]; // filename when opened
    BOOL      RevBytes = 0;
    
    
    // save a file
    void SaveToFile(void)
      { OPENFILENAME  ofn;        // filename struct
        HANDLE        fh;         // handle for opening files
        DWORD         fs;         // size of the data
        PTCHAR        fd;         // pointer to data
        // get the filename
        memset(&ofn,0,sizeof(ofn));
        ofn.lStructSize = sizeof(ofn);
        ofn.hwndOwner    = Wind[0];
        ofn.hInstance    = Inst;
        ofn.lpstrFilter  = L"All Files\0*.*\0\0";    
        ofn.lpstrFile    = FileName;
        ofn.nMaxFile     = MAX_PATH;
        ofn.lpstrTitle   = L"Save your work";
        ofn.Flags        = OFN_NONETWORKBUTTON |
                           OFN_HIDEREADONLY |
                           OFN_NOTESTFILECREATE |
                           OFN_OVERWRITEPROMPT;
        if (!GetSaveFileName(&ofn))
          return;
        // get unicode adjusted file size from edit control
        fs = (SendMessage(Wind[4],WM_GETTEXTLENGTH,0,0) * sizeof(TCHAR)); 
        if (fs < 1)
          return; 
        // create text buffer
        fd = malloc(fs);
        // get the text from the control
        SendMessage(Wind[4],WM_GETTEXT,fs,(LPARAM)fd);
        // open the file
        fh = CreateFile(FileName,GENERIC_WRITE,0,NULL,
                                CREATE_ALWAYS,
                                FILE_ATTRIBUTE_NORMAL |
                                FILE_FLAG_WRITE_THROUGH,NULL);
        // save the file
        if (fh != INVALID_HANDLE_VALUE)
          { WriteFile(fh,fd,fs,&fs,NULL);
            CloseHandle(fh); }
        free(fd); }
    
    
    
    // open a file
    void OpenFromFile(void)
      { OPENFILENAME  ofn;        // filename struct
        HANDLE        fh;         // handle for opening files
        DWORD         fs;         // size of the data
        PTCHAR        fd;         // pointer to data
        // get the filename
        memset(&ofn,0,sizeof(ofn));
        ofn.lStructSize = sizeof(ofn);
        ofn.hwndOwner    = Wind[0];
        ofn.hInstance    = Inst;
        ofn.lpstrFilter  = L"All Files\0*.*\0\0";    
        ofn.lpstrFile    = FileName;
        ofn.nMaxFile     = MAX_PATH;
        ofn.lpstrTitle   = L"Save your work";
        ofn.Flags        = OFN_NONETWORKBUTTON |
                           OFN_HIDEREADONLY |
                           OFN_NOTESTFILECREATE |
                           OFN_OVERWRITEPROMPT;
        if (!GetOpenFileName(&ofn))
          return;
        // open the file 
        fh = CreateFile(FileName,GENERIC_READ,FILE_SHARE_READ,NULL,
                                OPEN_EXISTING,
                                FILE_ATTRIBUTE_NORMAL,NULL);
        if (fh == INVALID_HANDLE_VALUE)
          { MessageBox(Wind[0],L"Error opening the file",L"OOPS!",0);
            return; }
        // get the file size
        fs = GetFileSize(fh,NULL) + sizeof(TCHAR);
        // create text buffer
        fd = malloc(fs);
        // clear to 0
        memset(fd,0,fs);
        // read from disk  
        ReadFile(fh,fd,fs,&fs,NULL);
        // close the file
        CloseHandle(fh);
        // put the text in the control
        SendMessage(Wind[4],WM_SETTEXT,fs,(LPARAM)fd);
        free(fd); }
    
    
    
    // resize the window
    VOID ResizeWindow(LPARAM lParm)
      { MoveWindow(Wind[4],60,2,LOWORD(lParm) - 62,HIWORD(lParm) - 4,1); }
    
    
    
    // Message Loop
    LRESULT CALLBACK MsgProc(HWND wnd,UINT msg,WPARAM wparm,LPARAM lparm)
      { switch (msg)
          { case WM_COMMAND :
              switch (LOWORD(wparm))
                { case 1001 :
                    OpenFromFile();
                    return 0;
                  case 1002 :
                    SaveToFile();
                    return 0;
                  case 1003 :
                    PostMessage(Wind[0],WM_CLOSE,0,0);
                    return 0;
                  default :
                    return DefWindowProc(wnd,msg,wparm,lparm); }
            case WM_SIZE  :
              ResizeWindow(lparm);
              return 0;
            case WM_CLOSE :         // close window
              DestroyWindow(Wind[0]);  
              return 0;
            case WM_DESTROY :       // NC Exit button
              PostQuitMessage(0); 
              return 0; 
            default :
              return DefWindowProc(wnd,msg,wparm,lparm); } }
    
    
    
    // create the window
    VOID CreateMainWindow(void)
      { WNDCLASS  wc;
        // register App Class
        memset(&wc,0,sizeof(wc));
        wc.style          = CS_CLASSDC;
        wc.hInstance      = Inst;
        wc.hCursor        = LoadCursor(NULL,IDC_ARROW);
        wc.hbrBackground  = CreateSolidBrush(GetSysColor(COLOR_3DFACE));
        wc.lpfnWndProc    = &MsgProc;
        wc.lpszClassName  = L"TINY_UNICODE";
        RegisterClass(&wc);
    
        // create the main window
        Wind[0] = CreateWindowEx( WS_EX_CONTROLPARENT,
                        L"TINY_UNICODE",L"Tiny Unicode Editor",
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,0,500,300,NULL,NULL,Inst,NULL);
        // buttons
        Wind[1] = CreateWindow(L"BUTTON",L"Open",
                        WS_CHILD | WS_VISIBLE | BS_FLAT,
                        2,2,50,25,Wind[0],(HMENU) 1001,Inst,NULL);
        Wind[2] = CreateWindow(L"BUTTON",L"Save",
                        WS_CHILD | WS_VISIBLE | BS_FLAT,
                        2,30,50,25,Wind[0],(HMENU) 1002,Inst,NULL);
        Wind[3] = CreateWindow(L"BUTTON",L"Quit",
                        WS_CHILD | WS_VISIBLE | BS_FLAT,
                        2,60,50,25,Wind[0],(HMENU) 1003,Inst,NULL);
        // edit window
        Wind[4] = CreateWindowEx(WS_EX_CLIENTEDGE,L"EDIT",NULL,
                        WS_CHILD | WS_VISIBLE |
                        ES_MULTILINE,
                        60,2,200,200,Wind[0],NULL,Inst,NULL);  
        UpdateWindow(Wind[0]);
        ShowWindow(Wind[0],SW_SHOWNORMAL);    }
    
    
    
             
    // Program Entry Procedure
    int WINAPI WinMain(HINSTANCE hinst, HINSTANCE pinst, LPSTR cmdl, int show)
      { MSG wmsg;
        // save instance handle
        Inst =    hinst;    
        // make the window
        CreateMainWindow();
        // dispatch window messages
        while (GetMessage(&wmsg,NULL,0,0))
          { TranslateMessage(&wmsg);
            DispatchMessage(&wmsg); }
    
        return 0; }

  5. #5
    Registered User carrotcake1029's Avatar
    Join Date
    Apr 2008
    Posts
    404
    Was trying to avoid global variables, but meh, I guess I could have worse things to worry about

  6. #6
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by carrotcake1029 View Post
    Was trying to avoid global variables, but meh, I guess I could have worse things to worry about
    Certain things HAVE to be globalized... otherwise your code becomes so horribly convoluted as to end up non-functional. Global variables are not a bad thing as long as you are mindful of scoping rules in C... A good example of variables that are best made global is window handles, there are times you will need them even on different source pages and to have to continuously struggle to rediscover them each time they are needed does nothing but slow your app to a crawl. The same is true of program settings, instance handles and many event object handles.

    The trick is to not make things global *unnecessarily*... it's not something to avoid when necessity speaks.


    My three main rules of success for windows programming...

    1) Always share settings and handles
    2) Never put code in switch statements; function calls only
    3) Remember to Free memory, handles etc. when done with them.

  7. #7
    Registered User carrotcake1029's Avatar
    Join Date
    Apr 2008
    Posts
    404
    Alright thanks for your input. Those rules seem logical to me and I think I'll make sure to take those into consideration.

    Thanks

  8. #8
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by carrotcake1029 View Post
    Alright thanks for your input. Those rules seem logical to me and I think I'll make sure to take those into consideration.

    Thanks
    No problems, mate. Good luck with the project.

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    >> HWND *edit1 = malloc(sizeof(HWND));
    >> edit1 = &temp;
    This is going to create a memory leak.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #10
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Did you try giving the edit a ID number and using SetDlgItemText()?

    Code:
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
        
        HWND edit1  = CreateWindow(
            "edit",
            "",
            WS_VISIBLE | WS_CHILD | WS_BORDER | ES_AUTOHSCROLL,
            5, 25,
            120, 20, hwnd,
            (HMENU)IDC_EDIT, 
            hInstance, NULL);
            
     }
    
    LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {    
        case WM_COMMAND:
            switch(LOWORD(wParam))
            {
                case ID_BUTTON1:
                {
                    szFile = shell_opendialog(szFile);
                    
                    if (lstrlen(szFile))//check the buffer has text not if it buffer exists?
                    {
                        SetDlgItemText( hwnd, IDC_EDIT, szFile );//set the edits text to the file name
                    }
    
                }
        ...
    }
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  11. #11
    Registered User carrotcake1029's Avatar
    Join Date
    Apr 2008
    Posts
    404
    And there is yet another function that could prove useful, thank you sir!

  12. #12
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by carrotcake1029 View Post
    And there is yet another function that could prove useful, thank you sir!
    Just in case you don't have it yet...

    Windows SDK Archive

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Retrieving Data from DLL
    By JJFMJR in forum C++ Programming
    Replies: 11
    Last Post: 08-18-2008, 07:44 AM
  2. classmember WndProc isn't called ...
    By Greenhorn__ in forum Windows Programming
    Replies: 10
    Last Post: 07-19-2008, 11:40 AM
  3. destroywindow() problem
    By algi in forum Windows Programming
    Replies: 6
    Last Post: 03-27-2005, 11:40 PM
  4. button in function
    By algi in forum Windows Programming
    Replies: 1
    Last Post: 03-21-2005, 11:12 PM
  5. opengl program as win API menu item
    By SAMSAM in forum Game Programming
    Replies: 1
    Last Post: 03-03-2003, 07:48 PM