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
Is your client actually calling DoItAll(), or are you still just calling LoadLibrary()?
gg
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.
>> I have tried both.
Don't do anything in DllMain. The client should call DoItAll() directly. You're DllMain() should simply return TRUE.
gg
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; }
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
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?
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
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.
Forget about using templates, there's no need.
This is as simple as it gets:
That should show your dialog. Start modifying it from there.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
gg
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.
>> 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
Here is my calling program:
Here is my dll code: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); }
and here is the text from inside the most recent Con2DLL.rc: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
I could have been a plumber, ya know!!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