Thread: Dialogbox from within a DLL

  1. #16
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Quote Originally Posted by JustMax View Post
    The problem is in the createdialog call on DllMain. I cannot get that dialog to show.
    so check the return value and if it fails - look at the GetLastError
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  2. #17
    Registered User JustMax's Avatar
    Join Date
    Jan 2009
    Posts
    59
    Ok, I have started from scratch. I created a dll that has one function named DoItAll. It only has three commands. The first displays a message box saying "we're here" the second should display the dialog IDD_DIALOG1, and the third command shows another message box saying " we have passed the dialog call."
    I created a simple dialog box that only has two buttons in it, inside this project. Then I built the dll.

    From my main program, I load the library and call DoItAll. I see the two message boxes but not the dialog box.

    Can anyone make this scenereo work? If so, can you tell me how?

    Thanks

  3. #18
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Is your client actually calling DoItAll(), or are you still just calling LoadLibrary()?

    gg

  4. #19
    Registered User JustMax's Avatar
    Join Date
    Jan 2009
    Posts
    59
    I have tried both.
    I am making headway though. I have found that, if I don't let Visual Studio create the dialog resource for me, I can get it to display. I am in the process of defining all of the components I need for the editor now.

    You guys have been a great help to me. I really appreciate it.

  5. #20
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    >> I have tried both.
    Don't do anything in DllMain. The client should call DoItAll() directly. You're DllMain() should simply return TRUE.

    gg

  6. #21
    Registered User JustMax's Avatar
    Join Date
    Jan 2009
    Posts
    59
    dllMain is empty now. Here is the next issue:

    I am now able to launch the dialog box from the dll but, if I add an edit control, I get an "Unhandled exception at 0x00000000 in Win2PRG.exe: 0xC0000005: Access violation reading location 0x00000000."

    If I remark it out and add a button instead, it works fine. Here is the code, you can see where I have remarked out some controls to test with:
    Code:
    extern "C" __declspec(dllexport) LRESULT DisplayMyMessage(HINSTANCE hinst, HWND hwndOwner, LPSTR lpszMessage)
    {
        HGLOBAL hgbl;
        LPDLGTEMPLATE lpdt;
        LPDLGITEMTEMPLATE lpdit;
        LPWORD lpw;
        LPWSTR lpwsz;
        LRESULT ret;
        int nchar;
    
        hgbl = GlobalAlloc(GMEM_ZEROINIT, 1024);
        if (!hgbl)
            return -1;
     
        lpdt = (LPDLGTEMPLATE)GlobalLock(hgbl);
     
        // Define a dialog box.
     
        lpdt->style = WS_POPUP | WS_BORDER | WS_SYSMENU | DS_MODALFRAME | WS_CAPTION;
        lpdt->cdit = 2;         // Number of controls
        lpdt->x  = 1;  lpdt->y  = 1;
        lpdt->cx = 200; lpdt->cy = 100;
    
        lpw = (LPWORD)(lpdt + 1);
        *lpw++ = 0;             // No menu
        *lpw++ = 0;             // Predefined dialog box class (by default)
    
        lpwsz = (LPWSTR)lpw;
        nchar = 1 + MultiByteToWideChar(CP_ACP, 0, "My Dialog", -1, lpwsz, 50);
        lpw += nchar;
    
        //-----------------------
        // Define an OK button.
        //-----------------------
        lpw = lpwAlign(lpw);    // Align DLGITEMTEMPLATE on DWORD boundary
        lpdit = (LPDLGITEMTEMPLATE)lpw;
        lpdit->x  = 100; lpdit->y  = 70; //position (left, top)
        lpdit->cx = 40; lpdit->cy = 15; //width and height
        lpdit->id = IDOK;       // OK button identifier
        lpdit->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;
    
        lpw = (LPWORD)(lpdit + 1);
        *lpw++ = 0xFFFF;
        *lpw++ = 0x0080;        // Button class
        lpwsz = (LPWSTR)lpw;
        nchar = 1 + MultiByteToWideChar(CP_ACP, 0, "OK", -1, lpwsz, 50);
        lpw += nchar;
        lpw = lpwAlign(lpw);    // Align creation data on DWORD boundary
        *lpw++ = 0;             // No creation data
    
        //-----------------------
        // Define a Help button.
        //-----------------------
        //lpw = lpwAlign(lpw);    // Align DLGITEMTEMPLATE on DWORD boundary
        //lpdit = (LPDLGITEMTEMPLATE)lpw;
        //lpdit->x  = 155; lpdit->y  = 70; //position (left, top)
        //lpdit->cx = 40;  lpdit->cy = 15; //width and height
        //lpdit->id = ID_HELP;    // Help button identifier
        //lpdit->style = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON;
        //lpw = (LPWORD)(lpdit + 1);
        //*lpw++ = 0xFFFF;
        //*lpw++ = 0x0080;        // Button class atom
        //lpwsz = (LPWSTR)lpw;
        //nchar = 1 + MultiByteToWideChar(CP_ACP, 0, "Help", -1, lpwsz, 50);
        //lpw += nchar;
        //lpw = lpwAlign(lpw);    // Align creation data on DWORD boundary
        //*lpw++ = 0;             // No creation data
    
    	//-----------------------
    	//   Define a EDIT.
    	//-----------------------
        lpw = lpwAlign (lpw);
    
        lpdit = (LPDLGITEMTEMPLATE) lpw;
        lpdit->x  = 10; lpdit->y  = 10;
        lpdit->cx = 80; lpdit->cy = 12;
        lpdit->id = ID_EDIT;    // Help button identifier
        lpdit->style = ES_LEFT | WS_BORDER | WS_TABSTOP | WS_CHILD | WS_VISIBLE;
    
        lpw = (LPWORD) (lpdit + 1);
        *lpw++ = 0xFFFF;
        *lpw++ = 0x0081;                 // edit class atom
        /*lpwsz = (LPWSTR) lpw;
        lstrcpyW(lpwsz, L"Edit");        // button label (Unicode)
        lpw = (LPWORD) (lpwsz + lstrlenW(lpwsz) + 1);*/
        *lpw++ = 0;                      // no creation data
    
    
    
    	//-----------------------
        // Define a static text control.
        //-----------------------
        //lpw = lpwAlign(lpw);    // Align DLGITEMTEMPLATE on DWORD boundary
        //lpdit = (LPDLGITEMTEMPLATE)lpw;
        //lpdit->x  = 10; lpdit->y  = 10;
        //lpdit->cx = 20; lpdit->cy = 10;
        //lpdit->id = ID_TEXT;    // Text identifier
        //lpdit->style = WS_CHILD | WS_VISIBLE/* | SS_LEFT*/ ;
        //lpw = (LPWORD)(lpdit + 1);
        //*lpw++ = 0xFFFF;
        //*lpw++ = 0x0082;        // Static class
    
        //for (lpwsz = (LPWSTR)lpw; *lpwsz++ = (WCHAR)*lpszMessage++;);
        //lpw = (LPWORD)lpwsz;
        //lpw = lpwAlign(lpw);    // Align creation data on DWORD boundary
        //*lpw++ = 0;             // No creation data
    
        GlobalUnlock(hgbl); 
        ret = DialogBoxIndirect(hinst, 
                               (LPDLGTEMPLATE)hgbl, 
                               hwndOwner, 
                               (DLGPROC)GoToProc); 
        GlobalFree(hgbl); 
        return ret; 
    }

  7. #22
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Why are using dialog templates manually instead of just using a resource editor? You're making it much harder than it needs to be.

    gg

  8. #23
    Registered User JustMax's Avatar
    Join Date
    Jan 2009
    Posts
    59
    Actually, my boss is making this much harder than it needs to be (but he's the one with the checkbook). If I create the dialog box with the resource editor, I cannot get the control to display at all (I posted that earlier).

    I have been tasked with creating a text editor that will be completely contained in a dll. My boss wants to pass me a variable that will identify the user, from that point he wants my dll to open a text editor, allow the user to open a text file (view, change, and save it), then exit my dll and return to his application.

    I am using Microsoft's example to create a dialog because I could not get a text editing dialog to work (in a dll) when I created it in the resource editor. I can do all of it in a stand alone application with no problem, it is doing it "completely" in a dll that is the issue.

    Any ideas?

  9. #24
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Using the resource editor, create your dialog resource and compile it into the DLL. In Visual Studio, you're simply editing a resource of/for the DLL project. When you call DialogBox(), the first parameter, hInstance, needs to be the HINSTANCE of your DLL. This is given to you in DllMain() for DLL_PROCESS_ATTACH, which you can save off into a global for later use.

    gg

  10. #25
    Registered User JustMax's Avatar
    Join Date
    Jan 2009
    Posts
    59
    I tried that earlier:

    "Ok, I have started from scratch. I created a dll that has one function named DoItAll. It only has three commands. The first displays a message box saying "we're here" the second should display the dialog IDD_DIALOG1, and the third command shows another message box saying " we have passed the dialog call."
    I created a simple dialog box that only has two buttons in it, inside this project. Then I built the dll.

    From my main program, I load the library and call DoItAll. I see the two message boxes but not the dialog box."

    That was when I switched to the template, which got the dialog to display but I cannot add the edit control without causing an error.

  11. #26
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Forget about using templates, there's no need.
    This is as simple as it gets:
    Code:
    #include <windows.h>
    #include "resource.h"
    
    HINSTANCE g_hInst = 0;
    
    BOOL WINAPI DllMain(HINSTANCE hInst, DWORD Reason, LPVOID Reserved)
    {
        if (Reason == DLL_PROCESS_ATTACH)
            g_hInst = hInst;
        return TRUE;
    }//DllMain
    
    INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, 
                                WPARAM wParam, LPARAM lParam)
    {
        return FALSE;
    }//DialogProc
    
    extern "C" __declspec(dllexport) 
    LRESULT DisplayMyMessage(HWND hwndOwner)
    {
        return (LRESULT)DialogBox(g_hInst, MAKEINTRESOURCE(IDD_DIALOG1), 
                                  hwndOwner, &DialogProc);
    }//DisplayMyMessage
    That should show your dialog. Start modifying it from there.

    gg

  12. #27
    Registered User JustMax's Avatar
    Join Date
    Jan 2009
    Posts
    59
    I'll give it a shot. Thanks for the help.

  13. #28
    Registered User JustMax's Avatar
    Join Date
    Jan 2009
    Posts
    59
    Tried it and still got nothing. I added:
    MessageBox(NULL,"Inside DiplayMyMessage.","Con2DLL",MB_OK);

    just before the return statement and now I see a my message box, so I know I am calling the function correctly, it just will not show a dialog box containing my edit control.

    I'll bet your about as frustrated with me as I am with this dll.

    Thanks for your efforts.

  14. #29
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    >> I see a my message box
    And if you change the text in the message box and re-compile, do you see the change? Just ensure you're using some old, stagnant copy of the dll...

    Post your resource file describing the dialog.

    gg

  15. #30
    Registered User JustMax's Avatar
    Join Date
    Jan 2009
    Posts
    59
    Here is my calling program:
    Code:
    // Win2PRG.cpp : Defines the entry point for the application.
    //
    #include "stdafx.h"
    #include "Win2PRG.h"
    #include "commdlg.h"
    #define MAXMODULE	50
    
    typedef void (WINAPI*cfunc)(); 
    cfunc DoItAll;
    cfunc DisplayMyMessage;
    
    OPENFILENAME ofn;
    
    int APIENTRY _tWinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPTSTR    lpCmdLine,
                         int       nCmdShow)
    {
           HINSTANCE hLib=LoadLibrary("Con2DLL.DLL");
           if(hLib==NULL) 
    	   {            
    		   MessageBox(NULL,"Unable to load library!","Error",MB_OK);
                 return 0;
           }       
    	   char mod[MAXMODULE];       
    	   GetModuleFileName((HMODULE)hLib, (LPTSTR)mod, MAXMODULE);
           MessageBox(NULL,"Library Loaded!!","Error",MB_OK);
           DisplayMyMessage =(cfunc)GetProcAddress((HMODULE)hLib, "DisplayMyMessage");
     	   if((DisplayMyMessage==NULL)) 
    	   {            
    		   MessageBox(NULL,"Unable to load function(s).","Error",MB_OK);
                FreeLibrary((HMODULE)hLib);
                return 0;
           }       
    	   DisplayMyMessage();
    	   FreeLibrary((HMODULE)hLib);  
    
     }
    Here is my dll code:
    Code:
    #include <windows.h>
    #include "resource.h"
    
    HINSTANCE g_hInst = 0;
    
    BOOL WINAPI DllMain(HINSTANCE hInst, DWORD Reason, LPVOID Reserved )
    {
        if (Reason == DLL_PROCESS_ATTACH)
            g_hInst = hInst;
        return TRUE;
    }//DllMain
    
    INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, 
                                WPARAM wParam, LPARAM lParam)
    {
        return FALSE;
    }//DialogProc
    
    extern "C" __declspec(dllexport) 
    LRESULT DisplayMyMessage(HWND hwndOwner)
    {
    		MessageBox(NULL,"Inside DiplayMyMessage.","Con2DLL",MB_OK);
    		DialogBox(g_hInst, MAKEINTRESOURCE(IDD_DIALOG1), 
                                  hwndOwner, &DialogProc);
        return (LRESULT)DialogBox(g_hInst, MAKEINTRESOURCE(IDD_DIALOG1), 
                                  hwndOwner, &DialogProc);
    }//DisplayMyMessage
    and here is the text from inside the most recent Con2DLL.rc:
    Code:
    // Microsoft Visual C++ generated resource script.
    //
    #include "resource.h"
    
    #define APSTUDIO_READONLY_SYMBOLS
    /////////////////////////////////////////////////////////////////////////////
    //
    // Generated from the TEXTINCLUDE 2 resource.
    //
    #include "afxres.h"
    
    /////////////////////////////////////////////////////////////////////////////
    #undef APSTUDIO_READONLY_SYMBOLS
    
    /////////////////////////////////////////////////////////////////////////////
    // English (U.S.) resources
    
    #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
    #ifdef _WIN32
    LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
    #pragma code_page(1252)
    #endif //_WIN32
    
    #ifdef APSTUDIO_INVOKED
    /////////////////////////////////////////////////////////////////////////////
    //
    // TEXTINCLUDE
    //
    
    1 TEXTINCLUDE 
    BEGIN
        "resource.h\0"
    END
    
    2 TEXTINCLUDE 
    BEGIN
        "#include ""afxres.h""\r\n"
        "\0"
    END
    
    3 TEXTINCLUDE 
    BEGIN
        "\r\n"
        "\0"
    END
    
    #endif    // APSTUDIO_INVOKED
    
    
    /////////////////////////////////////////////////////////////////////////////
    //
    // Dialog
    //
    
    IDD_DIALOG1 DIALOGEX 0, 0, 236, 158
    STYLE DS_LOCALEDIT | DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | 
        WS_CAPTION | WS_SYSMENU
    CAPTION "Property Page"
    FONT 8, "MS Shell Dlg", 0, 0, 0x0
    BEGIN
        LTEXT           "TODO: layout property page",IDC_STATIC,73,74,90,8
        EDITTEXT        IDC_EDIT1,7,7,222,144,ES_AUTOHSCROLL
    END
    
    
    /////////////////////////////////////////////////////////////////////////////
    //
    // DESIGNINFO
    //
    
    #ifdef APSTUDIO_INVOKED
    GUIDELINES DESIGNINFO 
    BEGIN
        IDD_DIALOG1, DIALOG
        BEGIN
            LEFTMARGIN, 7
            RIGHTMARGIN, 229
            TOPMARGIN, 7
            BOTTOMMARGIN, 151
        END
    END
    #endif    // APSTUDIO_INVOKED
    
    #endif    // English (U.S.) resources
    /////////////////////////////////////////////////////////////////////////////
    
    
    
    #ifndef APSTUDIO_INVOKED
    /////////////////////////////////////////////////////////////////////////////
    //
    // Generated from the TEXTINCLUDE 3 resource.
    //
    
    
    /////////////////////////////////////////////////////////////////////////////
    #endif    // not APSTUDIO_INVOKED
    I could have been a plumber, ya know!!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. non-MFC DLL with MFC app question.
    By Kempelen in forum Windows Programming
    Replies: 10
    Last Post: 08-20-2008, 07:11 AM
  2. dll communicating between each other
    By cloudy in forum C++ Programming
    Replies: 5
    Last Post: 06-17-2005, 02:20 AM
  3. DLL and std::string woes!
    By Magos in forum C++ Programming
    Replies: 7
    Last Post: 09-08-2004, 12:34 PM
  4. .lib vs .h vs .dll
    By Shadow12345 in forum C++ Programming
    Replies: 13
    Last Post: 01-01-2003, 05:29 AM
  5. Putting a DialogBox into a DLL?
    By xds4lx in forum Windows Programming
    Replies: 1
    Last Post: 11-17-2002, 12:59 AM