0

I have created a Win32 dll in Visua Studio 2015 that contains a dialog box, I use the hModule passed to DllMain () and use ShowWindow () to actually show the window, but dialog box doesn't show up.

I use LoadLibrary() to load this DLL in another project.

Where is the problem? Here is my code:

BOOL APIENTRY DllMain( HMODULE hModule,
                   DWORD  ul_reason_for_call,
                   LPVOID lpReserved,
                   HINSTANCE hinstDLL
                 )
{
    switch (ul_reason_for_call)
    {
        case DLL_PROCESS_ATTACH:
            HWND hDlg;
            MSG msg;
            BOOL ret;
            BOOL sts;

            InitCommonControls();
            hDlg = CreateDialogParam(hinstDLL, MAKEINTRESOURCE(IDD_DIALOG1), 0, DialogProc, 0);

            if (!hDlg) {
                MessageBoxA(NULL,GetLastErrorAsString().c_str(),"",MB_OK);
                return false;
            }

            sts = ShowWindow(hDlg, 1);

            if (!sts)
            {
                MessageBoxA(NULL, GetLastErrorAsString().c_str(), "", MB_OK);
                return false;
            }

            while ((ret = GetMessage(&msg, 0, 0, 0)) != 0) {
                if (ret == -1)
                    return -1;

                if (!IsDialogMessage(hDlg, &msg)) {
                    TranslateMessage(&msg);
                    DispatchMessage(&msg);
                }
            }
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DETACH:
            break;
    }
    return TRUE;
}
Paul Sanders
  • 24,133
  • 4
  • 26
  • 48
G-H-T
  • 11
  • 2
  • 1
    There are countless posts here explaining why you can't do this, or pretty much anything, in DllMain – David Heffernan Jun 13 '18 at 19:48
  • 3
    [You can't use any of those functions in your `DllMain()`](https://msdn.microsoft.com/en-us/library/windows/desktop/dn633971.aspx): "*You should **never** perform the following tasks from within DllMain: ... Call functions **in User32.dll** or Gdi32.dll.*. You can use `CreateThread()` instead to display your dialog in a worker thread: "*Creating a thread can work **if you do not synchronize with other threads**.*" However, the best option is to export a separate function to display your dialog, and then have the loading app call that function when needed, after the DLL has been loaded. – Remy Lebeau Jun 13 '18 at 19:50
  • Thank you guys, Should I write an export table and call this function ? – G-H-T Jun 13 '18 at 19:56
  • Yes. That's precisely what to do. – David Heffernan Jun 13 '18 at 20:43
  • It's done thank you David and Remy – G-H-T Jun 13 '18 at 21:00
  • @RemyLebeau I see that the full quote from the link you provide is "Creating a thread can work if you do not synchronize with other threads, but it is risky." Just what are they trying to say there, do you think? There are too many weazel words there for my liking. I think the truth of it is probably that _that_ thread can't do anything significant either until all the relevant DLL's have been initialised, and, in the general case, how can it know when that initialisation is complete? So, OP, just in case you were thinking of doing it that way, don't! – Paul Sanders Jun 14 '18 at 05:16
  • @G-H-T I edited your post, primarily to put DllMain in the title for future Google hits, but _please_, indent your code properly in future! – Paul Sanders Jun 14 '18 at 05:43
  • 1
    @PaulSanders: There are no restrictions with respect to the thread created from `DllMain`. It can do anything. The dangerous pattern is, if you synchronize with that thread after creating it, because it will not start executing, until `DllMain` with `DLL_THREAD_ATTACH` has run to completion. And `DllMain` will not be entered, until the code creating the thread has returned. If that waits to synchronize with a thread that hasn't started executing, you have an instant deadlock. – IInspectable Jun 14 '18 at 08:56
  • @IInspectable Yes, they say that about synchronising with the main thread explicitly and that's fine. But why ... _can_ work and ... _but it is risky_? What's the deal with that? Also, if the newly created thread tries to call into a DLL that hasn't been properly initialised yet, well, anything could happen. My point, really, not wanting to beat Remy up or anything, was that starting a new thread is unlikely to help you most times in cases such as these. – Paul Sanders Jun 14 '18 at 09:09
  • @PaulSanders: It is risky, because, in general, you do want to pass data to the newly created thread. That data needs to live long enough until the newly created thread has had a chance to pick it up, and signal, that it has done so. The general pattern is to have some sort of synchronization, which *will* deadlock. In this specific case, creating a thread *is* safe. You don't need to pass any data to it, and don't need to synchronize with it. You have to know, what you're doing. If in doubt, simply don't. – IInspectable Jun 14 '18 at 09:19
  • @IInspectable Yes, you have to know what you're doing. Absolutely, that applies to threading in general. And safe because we can rely on USER32 etc being up and running _at the time the thread is started_, I assume, with reference to the code as posted. – Paul Sanders Jun 14 '18 at 09:25
  • @Paul user32 doesn't run. Code runs, some of which may live in that module. You didn't understand the point about synchronisation though. The potential for deadlock arises because of the process wide loader lock. The fact the user32 has loaded doesn't make the issue go away. – David Heffernan Jun 15 '18 at 07:17
  • @David OK, I'll try again. I assume we can rely on USER32 being _initialised_ ... And I do know about the loader lock, I just didn't call it out explicitly. As RC would say, you're in danger of being banished to nitpickers' corner. – Paul Sanders Jun 15 '18 at 10:50
  • @PaulSanders Well, what does initialised actually mean in the context of loading a module. That's not a term I am familiar with. Precision matters, and nitpicking is essential. – David Heffernan Jun 15 '18 at 11:22
  • @David OK, I'm beginning to see what you're getting at here I will do some research and post a new question (in [winapi], + whatever). – Paul Sanders Jun 15 '18 at 14:35
  • @PaulSanders , sure. Thank you. – G-H-T Jun 15 '18 at 22:03

0 Answers0