www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Windows behaviour issue

reply "John C" <johnch_atms hotmail.com> writes:
Hi

I'm struggling to see why the following code results in odd behaviour on 
Windows XP SP2. It creates a main window and a combo box, but the combo 
box's dropdown doesn't react correctly to mouse clicks - it should disappear 
when the parent window is clicked, but it remains visible until the parent 
loses the focus. Items in the dropdown should also get highlighted as the 
mouse moves over it, but don't.

The equivalent code in C++, almost identical, works perfectly. I'd be 
grateful if someone could diagnose what's going on. No exceptions are 
thrown, and error checking reveals nothing weird.

Cheers.

    import std.c.windows.windows;

    // WinMain etc. omitted for brevity.

    extern (Windows) LPARAM wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, 
LPARAM lParam) {
        switch (uMsg) {

            case WM_CREATE:
                HWND comboBoxHandle = CreateWindowExA(0, "COMBOBOX", "", 
WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | CBS_HASSTRINGS, 10, 10, 150, 24, 
hWnd, null, null, null);
                SendMessageA(comboBoxHandle, CB_ADDSTRING, 0, 
cast(LPARAM)toStringz("Item one"));
                SendMessageA(comboBoxHandle, CB_ADDSTRING, 0, 
cast(LPARAM)toStringz("Item two"));

                break;

            default:
                break;
        }
        return DefWindowProcA(hWnd, uMsg, wParam, lParam);
    }

    void createMainWindow() {
        InitCommonControls();

        char[] className = "TestWindowClass";

        WNDCLASSA wc; // makes no difference if this is zero'd out or not
        wc.lpfnWndProc = &wndProc;
        wc.lpszClassName = toStringz(className);
        wc.hInstance = GetModuleHandleA(null);
        RegisterClassA(&wc);

        HWND mainWindowHandle = CreateWindowExA(0, toStringz(className), "", 
WS_OVERLAPPEDWINDOW, 0, 0, 500, 500, null, null, null, null);
        ShowWindow(mainWindowHandle, SW_SHOW);
    }
Feb 25 2005
parent reply "Matthew" <admin stlsoft.dot.dot.dot.dot.org> writes:
There's no dialog manager!


"John C" <johnch_atms hotmail.com> wrote in message 
news:cvob5f$1q0o$1 digitaldaemon.com...
 Hi

 I'm struggling to see why the following code results in odd behaviour 
 on Windows XP SP2. It creates a main window and a combo box, but the 
 combo box's dropdown doesn't react correctly to mouse clicks - it 
 should disappear when the parent window is clicked, but it remains 
 visible until the parent loses the focus. Items in the dropdown should 
 also get highlighted as the mouse moves over it, but don't.

 The equivalent code in C++, almost identical, works perfectly. I'd be 
 grateful if someone could diagnose what's going on. No exceptions are 
 thrown, and error checking reveals nothing weird.

 Cheers.

    import std.c.windows.windows;

    // WinMain etc. omitted for brevity.

    extern (Windows) LPARAM wndProc(HWND hWnd, UINT uMsg, WPARAM 
 wParam, LPARAM lParam) {
        switch (uMsg) {

            case WM_CREATE:
                HWND comboBoxHandle = CreateWindowExA(0, "COMBOBOX", 
 "", WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | CBS_HASSTRINGS, 10, 10, 
 150, 24, hWnd, null, null, null);
                SendMessageA(comboBoxHandle, CB_ADDSTRING, 0, 
 cast(LPARAM)toStringz("Item one"));
                SendMessageA(comboBoxHandle, CB_ADDSTRING, 0, 
 cast(LPARAM)toStringz("Item two"));

                break;

            default:
                break;
        }
        return DefWindowProcA(hWnd, uMsg, wParam, lParam);
    }

    void createMainWindow() {
        InitCommonControls();

        char[] className = "TestWindowClass";

        WNDCLASSA wc; // makes no difference if this is zero'd out or 
 not
        wc.lpfnWndProc = &wndProc;
        wc.lpszClassName = toStringz(className);
        wc.hInstance = GetModuleHandleA(null);
        RegisterClassA(&wc);

        HWND mainWindowHandle = CreateWindowExA(0, 
 toStringz(className), "", WS_OVERLAPPEDWINDOW, 0, 0, 500, 500, null, 
 null, null, null);
        ShowWindow(mainWindowHandle, SW_SHOW);
    }

 

Feb 25 2005
parent reply "John C" <johnch_atms hotmail.com> writes:
Do you mean message pump? I do set that up with GetMessage, et al (I just 
didn't include it in my post).

"Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message 
news:cvof52$1te3$1 digitaldaemon.com...
 There's no dialog manager!


 "John C" <johnch_atms hotmail.com> wrote in message 
 news:cvob5f$1q0o$1 digitaldaemon.com...
 Hi

 I'm struggling to see why the following code results in odd behaviour on 
 Windows XP SP2. It creates a main window and a combo box, but the combo 
 box's dropdown doesn't react correctly to mouse clicks - it should 
 disappear when the parent window is clicked, but it remains visible until 
 the parent loses the focus. Items in the dropdown should also get 
 highlighted as the mouse moves over it, but don't.

 The equivalent code in C++, almost identical, works perfectly. I'd be 
 grateful if someone could diagnose what's going on. No exceptions are 
 thrown, and error checking reveals nothing weird.

 Cheers.

    import std.c.windows.windows;

    // WinMain etc. omitted for brevity.

    extern (Windows) LPARAM wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, 
 LPARAM lParam) {
        switch (uMsg) {

            case WM_CREATE:
                HWND comboBoxHandle = CreateWindowExA(0, "COMBOBOX", "", 
 WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | CBS_HASSTRINGS, 10, 10, 150, 24, 
 hWnd, null, null, null);
                SendMessageA(comboBoxHandle, CB_ADDSTRING, 0, 
 cast(LPARAM)toStringz("Item one"));
                SendMessageA(comboBoxHandle, CB_ADDSTRING, 0, 
 cast(LPARAM)toStringz("Item two"));

                break;

            default:
                break;
        }
        return DefWindowProcA(hWnd, uMsg, wParam, lParam);
    }

    void createMainWindow() {
        InitCommonControls();

        char[] className = "TestWindowClass";

        WNDCLASSA wc; // makes no difference if this is zero'd out or not
        wc.lpfnWndProc = &wndProc;
        wc.lpszClassName = toStringz(className);
        wc.hInstance = GetModuleHandleA(null);
        RegisterClassA(&wc);

        HWND mainWindowHandle = CreateWindowExA(0, toStringz(className), 
 "", WS_OVERLAPPEDWINDOW, 0, 0, 500, 500, null, null, null, null);
        ShowWindow(mainWindowHandle, SW_SHOW);
    }


Feb 26 2005
parent reply "Matthew" <admin stlsoft.dot.dot.dot.dot.org> writes:
No, the dialog manager is an internal component to Windows that is 
accessed by DialogBox or DialogBoxParam.

What you've done is effectively create a modeless dialog, for which 
you'd have to dispatch the dialog messages yourself. This can be done by 
using IsDialogMessage() as in:

    while(GetMessage( . . . ))
    {
        if(!IsDialogMessage(mainWindowHandle, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

But you're generally better off using DialogBoxParam()




"John C" <johnch_atms hotmail.com> wrote in message 
news:cvpemd$2s4p$1 digitaldaemon.com...
 Do you mean message pump? I do set that up with GetMessage, et al (I 
 just didn't include it in my post).

 "Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message 
 news:cvof52$1te3$1 digitaldaemon.com...
 There's no dialog manager!


 "John C" <johnch_atms hotmail.com> wrote in message 
 news:cvob5f$1q0o$1 digitaldaemon.com...
 Hi

 I'm struggling to see why the following code results in odd 
 behaviour on Windows XP SP2. It creates a main window and a combo 
 box, but the combo box's dropdown doesn't react correctly to mouse 
 clicks - it should disappear when the parent window is clicked, but 
 it remains visible until the parent loses the focus. Items in the 
 dropdown should also get highlighted as the mouse moves over it, but 
 don't.

 The equivalent code in C++, almost identical, works perfectly. I'd 
 be grateful if someone could diagnose what's going on. No exceptions 
 are thrown, and error checking reveals nothing weird.

 Cheers.

    import std.c.windows.windows;

    // WinMain etc. omitted for brevity.

    extern (Windows) LPARAM wndProc(HWND hWnd, UINT uMsg, WPARAM 
 wParam, LPARAM lParam) {
        switch (uMsg) {

            case WM_CREATE:
                HWND comboBoxHandle = CreateWindowExA(0, "COMBOBOX", 
 "", WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | CBS_HASSTRINGS, 10, 10, 
 150, 24, hWnd, null, null, null);
                SendMessageA(comboBoxHandle, CB_ADDSTRING, 0, 
 cast(LPARAM)toStringz("Item one"));
                SendMessageA(comboBoxHandle, CB_ADDSTRING, 0, 
 cast(LPARAM)toStringz("Item two"));

                break;

            default:
                break;
        }
        return DefWindowProcA(hWnd, uMsg, wParam, lParam);
    }

    void createMainWindow() {
        InitCommonControls();

        char[] className = "TestWindowClass";

        WNDCLASSA wc; // makes no difference if this is zero'd out or 
 not
        wc.lpfnWndProc = &wndProc;
        wc.lpszClassName = toStringz(className);
        wc.hInstance = GetModuleHandleA(null);
        RegisterClassA(&wc);

        HWND mainWindowHandle = CreateWindowExA(0, 
 toStringz(className), "", WS_OVERLAPPEDWINDOW, 0, 0, 500, 500, null, 
 null, null, null);
        ShowWindow(mainWindowHandle, SW_SHOW);
    }



Feb 26 2005
parent reply "John C" <johnch_atms hotmail.com> writes:
Thanks for the suggestion. Generally an application's main window is 
modeless, and using the GetMessage mechanism is fairly common. Adding 
IsDialogMessage doesn't fix the issue with the child control's behaviour, 
however.

I've tested this on a few Windows machines, all exhibiting the same problem. 
I tried out one of the other GUI libraries (DFL 
http://www.dprogramming.com/dfl.php) and it shares this peculiarity.

What's bizarre is that the same program works correctly when written in 
C/C++, and I'm beginning to suspect that the D compiler is somehow producing 
buggy executables. If I substitute the combo box with other common controls 
in the same code I posted - list box, button, treeview - everything's fine. 
So annoying that one control (which I plan to use in quite a few places in 
my application) is misbehaving.

"Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message 
news:cvpg0u$3082$1 digitaldaemon.com...
 No, the dialog manager is an internal component to Windows that is 
 accessed by DialogBox or DialogBoxParam.

 What you've done is effectively create a modeless dialog, for which you'd 
 have to dispatch the dialog messages yourself. This can be done by using 
 IsDialogMessage() as in:

    while(GetMessage( . . . ))
    {
        if(!IsDialogMessage(mainWindowHandle, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

 But you're generally better off using DialogBoxParam()




 "John C" <johnch_atms hotmail.com> wrote in message 
 news:cvpemd$2s4p$1 digitaldaemon.com...
 Do you mean message pump? I do set that up with GetMessage, et al (I just 
 didn't include it in my post).

 "Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message 
 news:cvof52$1te3$1 digitaldaemon.com...
 There's no dialog manager!


 "John C" <johnch_atms hotmail.com> wrote in message 
 news:cvob5f$1q0o$1 digitaldaemon.com...
 Hi

 I'm struggling to see why the following code results in odd behaviour 
 on Windows XP SP2. It creates a main window and a combo box, but the 
 combo box's dropdown doesn't react correctly to mouse clicks - it 
 should disappear when the parent window is clicked, but it remains 
 visible until the parent loses the focus. Items in the dropdown should 
 also get highlighted as the mouse moves over it, but don't.

 The equivalent code in C++, almost identical, works perfectly. I'd be 
 grateful if someone could diagnose what's going on. No exceptions are 
 thrown, and error checking reveals nothing weird.

 Cheers.

    import std.c.windows.windows;

    // WinMain etc. omitted for brevity.

    extern (Windows) LPARAM wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, 
 LPARAM lParam) {
        switch (uMsg) {

            case WM_CREATE:
                HWND comboBoxHandle = CreateWindowExA(0, "COMBOBOX", "", 
 WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | CBS_HASSTRINGS, 10, 10, 150, 24, 
 hWnd, null, null, null);
                SendMessageA(comboBoxHandle, CB_ADDSTRING, 0, 
 cast(LPARAM)toStringz("Item one"));
                SendMessageA(comboBoxHandle, CB_ADDSTRING, 0, 
 cast(LPARAM)toStringz("Item two"));

                break;

            default:
                break;
        }
        return DefWindowProcA(hWnd, uMsg, wParam, lParam);
    }

    void createMainWindow() {
        InitCommonControls();

        char[] className = "TestWindowClass";

        WNDCLASSA wc; // makes no difference if this is zero'd out or 
 not
        wc.lpfnWndProc = &wndProc;
        wc.lpszClassName = toStringz(className);
        wc.hInstance = GetModuleHandleA(null);
        RegisterClassA(&wc);

        HWND mainWindowHandle = CreateWindowExA(0, toStringz(className), 
 "", WS_OVERLAPPEDWINDOW, 0, 0, 500, 500, null, null, null, null);
        ShowWindow(mainWindowHandle, SW_SHOW);
    }




Feb 26 2005
parent reply "Matthew" <admin stlsoft.dot.dot.dot.dot.org> writes:
Well, I stand by what I've said. The dialog manager is one of the oldest 
parts of Windows, and one of the most widely understood.

I suspect there's a subtle bug in your D implementation, and suggest you 
post the full code.

"John C" <johnch_atms hotmail.com> wrote in message 
news:cvpjb9$1bs$1 digitaldaemon.com...
 Thanks for the suggestion. Generally an application's main window is 
 modeless, and using the GetMessage mechanism is fairly common. Adding 
 IsDialogMessage doesn't fix the issue with the child control's 
 behaviour, however.

 I've tested this on a few Windows machines, all exhibiting the same 
 problem. I tried out one of the other GUI libraries (DFL 
 http://www.dprogramming.com/dfl.php) and it shares this peculiarity.

 What's bizarre is that the same program works correctly when written 
 in C/C++, and I'm beginning to suspect that the D compiler is somehow 
 producing buggy executables. If I substitute the combo box with other 
 common controls in the same code I posted - list box, button, 
 treeview - everything's fine. So annoying that one control (which I 
 plan to use in quite a few places in my application) is misbehaving.

 "Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message 
 news:cvpg0u$3082$1 digitaldaemon.com...
 No, the dialog manager is an internal component to Windows that is 
 accessed by DialogBox or DialogBoxParam.

 What you've done is effectively create a modeless dialog, for which 
 you'd have to dispatch the dialog messages yourself. This can be done 
 by using IsDialogMessage() as in:

    while(GetMessage( . . . ))
    {
        if(!IsDialogMessage(mainWindowHandle, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

 But you're generally better off using DialogBoxParam()




 "John C" <johnch_atms hotmail.com> wrote in message 
 news:cvpemd$2s4p$1 digitaldaemon.com...
 Do you mean message pump? I do set that up with GetMessage, et al (I 
 just didn't include it in my post).

 "Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message 
 news:cvof52$1te3$1 digitaldaemon.com...
 There's no dialog manager!


 "John C" <johnch_atms hotmail.com> wrote in message 
 news:cvob5f$1q0o$1 digitaldaemon.com...
 Hi

 I'm struggling to see why the following code results in odd 
 behaviour on Windows XP SP2. It creates a main window and a combo 
 box, but the combo box's dropdown doesn't react correctly to mouse 
 clicks - it should disappear when the parent window is clicked, 
 but it remains visible until the parent loses the focus. Items in 
 the dropdown should also get highlighted as the mouse moves over 
 it, but don't.

 The equivalent code in C++, almost identical, works perfectly. I'd 
 be grateful if someone could diagnose what's going on. No 
 exceptions are thrown, and error checking reveals nothing weird.

 Cheers.

    import std.c.windows.windows;

    // WinMain etc. omitted for brevity.

    extern (Windows) LPARAM wndProc(HWND hWnd, UINT uMsg, WPARAM 
 wParam, LPARAM lParam) {
        switch (uMsg) {

            case WM_CREATE:
                HWND comboBoxHandle = CreateWindowExA(0, 
 "COMBOBOX", "", WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | 
 CBS_HASSTRINGS, 10, 10, 150, 24, hWnd, null, null, null);
                SendMessageA(comboBoxHandle, CB_ADDSTRING, 0, 
 cast(LPARAM)toStringz("Item one"));
                SendMessageA(comboBoxHandle, CB_ADDSTRING, 0, 
 cast(LPARAM)toStringz("Item two"));

                break;

            default:
                break;
        }
        return DefWindowProcA(hWnd, uMsg, wParam, lParam);
    }

    void createMainWindow() {
        InitCommonControls();

        char[] className = "TestWindowClass";

        WNDCLASSA wc; // makes no difference if this is zero'd out 
 or not
        wc.lpfnWndProc = &wndProc;
        wc.lpszClassName = toStringz(className);
        wc.hInstance = GetModuleHandleA(null);
        RegisterClassA(&wc);

        HWND mainWindowHandle = CreateWindowExA(0, 
 toStringz(className), "", WS_OVERLAPPEDWINDOW, 0, 0, 500, 500, 
 null, null, null, null);
        ShowWindow(mainWindowHandle, SW_SHOW);
    }





Feb 26 2005
parent reply "John C" <johnch_atms hotmail.com> writes:
You're right, the DialogBoxParam route is common, too. I'll try that later 
today, but in the meantime here's the complete program. To repro: push the 
combo box arrow to display the dropdown, and then click in the parent's 
client area; the dropdown list remains visible, whereas it should get 
dismissed.

Command line: dmd testapp -debug -g -inline -L/EXET:NT -L/SU:windows 
comctl32.lib

module testapp;

import std.string;
import std.c.windows.windows;

extern (C) void gc_init();
extern (C) void gc_term();
extern (C) void _minit();
extern (C) void _moduleCtor();

extern (Windows) void InitCommonControls();
extern (Windows) BOOL IsDialogMessageA(HWND, MSG*);

const int CBS_DROPDOWN = 0x0002;
const int CBS_HASSTRINGS = 0x0200;
const uint CB_ADDSTRING = 0x0143;

HWND mainWindowHandle;

extern (Windows) LPARAM wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM 
lParam) {
  switch (uMsg) {

    case WM_DESTROY:
      PostQuitMessage(0);
      break;

    case WM_CREATE:
      HWND comboBoxHandle = CreateWindowExA(0, "COMBOBOX", "", WS_CHILD | 
WS_VISIBLE | CBS_DROPDOWN | CBS_HASSTRINGS, 10, 10, 150, 100, hWnd, null, 
null, null);
      SendMessageA(comboBoxHandle, CB_ADDSTRING, 0, 
cast(LPARAM)toStringz("Item one"));
      SendMessageA(comboBoxHandle, CB_ADDSTRING, 0, 
cast(LPARAM)toStringz("Item two"));
      break;

    default:
      break;
  }
  return DefWindowProcA(hWnd, uMsg, wParam, lParam);
}

void createMainWindow() {
  InitCommonControls();

  char[] className = "TestWindowClass";

  WNDCLASSA wc;
  ((ubyte*)&wc)[0 .. wc.sizeof] = 0;
  wc.lpfnWndProc = &wndProc;
  wc.hCursor = LoadCursorA(null, IDC_ARROW);
  wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
  wc.lpfnWndProc = &wndProc;
  wc.lpszClassName = toStringz(className);
  wc.hInstance = GetModuleHandleA(null);
  RegisterClassA(&wc);

  mainWindowHandle = CreateWindowExA(0, toStringz(className), "", 
WS_OVERLAPPEDWINDOW, 0, 0, 500, 500, null, null, null, null);
  ShowWindow(mainWindowHandle, SW_SHOW);
}

int main() {
  createMainWindow();
  MSG msg;
  while (GetMessageA(&msg, null, 0, 0)) {
    if (!IsDialogMessageA(mainWindowHandle, &msg)) {
      TranslateMessage(&msg);
      DispatchMessageA(&msg);
    }
  }
  return msg.wParam;
}

extern (Windows) int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
LPSTR lpCmdLine, int nCmdShow) {
  int result = 0;
  gc_init();
  _minit();
  try {
    _moduleCtor();
    result = main();
  }
  catch (Object o) {
    result = 0;
  }
  gc_term();
  return result;
}

"Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message 
news:cvpkpq$29q$1 digitaldaemon.com...
 Well, I stand by what I've said. The dialog manager is one of the oldest 
 parts of Windows, and one of the most widely understood.

 I suspect there's a subtle bug in your D implementation, and suggest you 
 post the full code.

 "John C" <johnch_atms hotmail.com> wrote in message 
 news:cvpjb9$1bs$1 digitaldaemon.com...
 Thanks for the suggestion. Generally an application's main window is 
 modeless, and using the GetMessage mechanism is fairly common. Adding 
 IsDialogMessage doesn't fix the issue with the child control's behaviour, 
 however.

 I've tested this on a few Windows machines, all exhibiting the same 
 problem. I tried out one of the other GUI libraries (DFL 
 http://www.dprogramming.com/dfl.php) and it shares this peculiarity.

 What's bizarre is that the same program works correctly when written in 
 C/C++, and I'm beginning to suspect that the D compiler is somehow 
 producing buggy executables. If I substitute the combo box with other 
 common controls in the same code I posted - list box, button, treeview - 
 everything's fine. So annoying that one control (which I plan to use in 
 quite a few places in my application) is misbehaving.

 "Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message 
 news:cvpg0u$3082$1 digitaldaemon.com...
 No, the dialog manager is an internal component to Windows that is 
 accessed by DialogBox or DialogBoxParam.

 What you've done is effectively create a modeless dialog, for which 
 you'd have to dispatch the dialog messages yourself. This can be done by 
 using IsDialogMessage() as in:

    while(GetMessage( . . . ))
    {
        if(!IsDialogMessage(mainWindowHandle, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

 But you're generally better off using DialogBoxParam()




 "John C" <johnch_atms hotmail.com> wrote in message 
 news:cvpemd$2s4p$1 digitaldaemon.com...
 Do you mean message pump? I do set that up with GetMessage, et al (I 
 just didn't include it in my post).

 "Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message 
 news:cvof52$1te3$1 digitaldaemon.com...
 There's no dialog manager!


 "John C" <johnch_atms hotmail.com> wrote in message 
 news:cvob5f$1q0o$1 digitaldaemon.com...
 Hi

 I'm struggling to see why the following code results in odd behaviour 
 on Windows XP SP2. It creates a main window and a combo box, but the 
 combo box's dropdown doesn't react correctly to mouse clicks - it 
 should disappear when the parent window is clicked, but it remains 
 visible until the parent loses the focus. Items in the dropdown 
 should also get highlighted as the mouse moves over it, but don't.

 The equivalent code in C++, almost identical, works perfectly. I'd be 
 grateful if someone could diagnose what's going on. No exceptions are 
 thrown, and error checking reveals nothing weird.

 Cheers.

    import std.c.windows.windows;

    // WinMain etc. omitted for brevity.

    extern (Windows) LPARAM wndProc(HWND hWnd, UINT uMsg, WPARAM 
 wParam, LPARAM lParam) {
        switch (uMsg) {

            case WM_CREATE:
                HWND comboBoxHandle = CreateWindowExA(0, "COMBOBOX", 
 "", WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | CBS_HASSTRINGS, 10, 10, 
 150, 24, hWnd, null, null, null);
                SendMessageA(comboBoxHandle, CB_ADDSTRING, 0, 
 cast(LPARAM)toStringz("Item one"));
                SendMessageA(comboBoxHandle, CB_ADDSTRING, 0, 
 cast(LPARAM)toStringz("Item two"));

                break;

            default:
                break;
        }
        return DefWindowProcA(hWnd, uMsg, wParam, lParam);
    }

    void createMainWindow() {
        InitCommonControls();

        char[] className = "TestWindowClass";

        WNDCLASSA wc; // makes no difference if this is zero'd out or 
 not
        wc.lpfnWndProc = &wndProc;
        wc.lpszClassName = toStringz(className);
        wc.hInstance = GetModuleHandleA(null);
        RegisterClassA(&wc);

        HWND mainWindowHandle = CreateWindowExA(0, 
 toStringz(className), "", WS_OVERLAPPEDWINDOW, 0, 0, 500, 500, null, 
 null, null, null);
        ShowWindow(mainWindowHandle, SW_SHOW);
    }






Feb 26 2005
next sibling parent "Matthew" <admin stlsoft.dot.dot.dot.dot.org> writes:
There's a short answer, and a long answer.

    The short answer is that the combo box is not receiving WM_KILLFOCUS

By adding a second combo, I can show that clicking on it will cause it 
to grab the focus, such that the previous one will receive WM_KILLFOCUS. 
Or, by adding a WM_LBUTTONDOWN handler into the wndProc(), as in:

    case WM_LBUTTONDOWN:
        SetFocus(mainWindowHandle);
        break;

will also do it.

This kind of thing is that the dialog manager will handle. 
IsDialogMessage() will also do this when given a dialog window, via 
CreateDialog. But since you've used CreateWindow(), all you're getting 
is the totally default processing of DefWindowProc(), which is to say 
very little indeed.

I strongly advise you to either use DialogBox(Param) to get a modal 
dialog, or CreateDialog(Param) for a modeless dialog. Otherwise, you'll 
have an enormous amount of boilerplate coding to do. For a taster, check 
out my article on dialog handling in December 2002's WDJ - 
http://www.windevnet.com/documents/win0212c/

Cheers

Matthew

P.S. If you're interested, you might check out some of my other 
blithersome rants at http://www.synesis.com.au/articles.html. :-)



"John C" <johnch_atms hotmail.com> wrote in message 
news:cvpnnq$4m3$1 digitaldaemon.com...
 You're right, the DialogBoxParam route is common, too. I'll try that 
 later today, but in the meantime here's the complete program. To 
 repro: push the combo box arrow to display the dropdown, and then 
 click in the parent's client area; the dropdown list remains visible, 
 whereas it should get dismissed.

 Command line: dmd testapp -debug -g -inline -L/EXET:NT -L/SU:windows 
 comctl32.lib

 module testapp;

 import std.string;
 import std.c.windows.windows;

 extern (C) void gc_init();
 extern (C) void gc_term();
 extern (C) void _minit();
 extern (C) void _moduleCtor();

 extern (Windows) void InitCommonControls();
 extern (Windows) BOOL IsDialogMessageA(HWND, MSG*);

 const int CBS_DROPDOWN = 0x0002;
 const int CBS_HASSTRINGS = 0x0200;
 const uint CB_ADDSTRING = 0x0143;

 HWND mainWindowHandle;

 extern (Windows) LPARAM wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, 
 LPARAM lParam) {
  switch (uMsg) {

    case WM_DESTROY:
      PostQuitMessage(0);
      break;

    case WM_CREATE:
      HWND comboBoxHandle = CreateWindowExA(0, "COMBOBOX", "", WS_CHILD 
 | WS_VISIBLE | CBS_DROPDOWN | CBS_HASSTRINGS, 10, 10, 150, 100, hWnd, 
 null, null, null);
      SendMessageA(comboBoxHandle, CB_ADDSTRING, 0, 
 cast(LPARAM)toStringz("Item one"));
      SendMessageA(comboBoxHandle, CB_ADDSTRING, 0, 
 cast(LPARAM)toStringz("Item two"));
      break;

    default:
      break;
  }
  return DefWindowProcA(hWnd, uMsg, wParam, lParam);
 }

 void createMainWindow() {
  InitCommonControls();

  char[] className = "TestWindowClass";

  WNDCLASSA wc;
  ((ubyte*)&wc)[0 .. wc.sizeof] = 0;
  wc.lpfnWndProc = &wndProc;
  wc.hCursor = LoadCursorA(null, IDC_ARROW);
  wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
  wc.lpfnWndProc = &wndProc;
  wc.lpszClassName = toStringz(className);
  wc.hInstance = GetModuleHandleA(null);
  RegisterClassA(&wc);

  mainWindowHandle = CreateWindowExA(0, toStringz(className), "", 
 WS_OVERLAPPEDWINDOW, 0, 0, 500, 500, null, null, null, null);
  ShowWindow(mainWindowHandle, SW_SHOW);
 }

 int main() {
  createMainWindow();
  MSG msg;
  while (GetMessageA(&msg, null, 0, 0)) {
    if (!IsDialogMessageA(mainWindowHandle, &msg)) {
      TranslateMessage(&msg);
      DispatchMessageA(&msg);
    }
  }
  return msg.wParam;
 }

 extern (Windows) int WinMain(HINSTANCE hInstance, HINSTANCE 
 hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
  int result = 0;
  gc_init();
  _minit();
  try {
    _moduleCtor();
    result = main();
  }
  catch (Object o) {
    result = 0;
  }
  gc_term();
  return result;
 }

 "Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message 
 news:cvpkpq$29q$1 digitaldaemon.com...
 Well, I stand by what I've said. The dialog manager is one of the 
 oldest parts of Windows, and one of the most widely understood.

 I suspect there's a subtle bug in your D implementation, and suggest 
 you post the full code.

 "John C" <johnch_atms hotmail.com> wrote in message 
 news:cvpjb9$1bs$1 digitaldaemon.com...
 Thanks for the suggestion. Generally an application's main window is 
 modeless, and using the GetMessage mechanism is fairly common. 
 Adding IsDialogMessage doesn't fix the issue with the child 
 control's behaviour, however.

 I've tested this on a few Windows machines, all exhibiting the same 
 problem. I tried out one of the other GUI libraries (DFL 
 http://www.dprogramming.com/dfl.php) and it shares this peculiarity.

 What's bizarre is that the same program works correctly when written 
 in C/C++, and I'm beginning to suspect that the D compiler is 
 somehow producing buggy executables. If I substitute the combo box 
 with other common controls in the same code I posted - list box, 
 button, treeview - everything's fine. So annoying that one control 
 (which I plan to use in quite a few places in my application) is 
 misbehaving.

 "Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message 
 news:cvpg0u$3082$1 digitaldaemon.com...
 No, the dialog manager is an internal component to Windows that is 
 accessed by DialogBox or DialogBoxParam.

 What you've done is effectively create a modeless dialog, for which 
 you'd have to dispatch the dialog messages yourself. This can be 
 done by using IsDialogMessage() as in:

    while(GetMessage( . . . ))
    {
        if(!IsDialogMessage(mainWindowHandle, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

 But you're generally better off using DialogBoxParam()




 "John C" <johnch_atms hotmail.com> wrote in message 
 news:cvpemd$2s4p$1 digitaldaemon.com...
 Do you mean message pump? I do set that up with GetMessage, et al 
 (I just didn't include it in my post).

 "Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message 
 news:cvof52$1te3$1 digitaldaemon.com...
 There's no dialog manager!


 "John C" <johnch_atms hotmail.com> wrote in message 
 news:cvob5f$1q0o$1 digitaldaemon.com...
 Hi

 I'm struggling to see why the following code results in odd 
 behaviour on Windows XP SP2. It creates a main window and a 
 combo box, but the combo box's dropdown doesn't react correctly 
 to mouse clicks - it should disappear when the parent window is 
 clicked, but it remains visible until the parent loses the 
 focus. Items in the dropdown should also get highlighted as the 
 mouse moves over it, but don't.

 The equivalent code in C++, almost identical, works perfectly. 
 I'd be grateful if someone could diagnose what's going on. No 
 exceptions are thrown, and error checking reveals nothing weird.

 Cheers.

    import std.c.windows.windows;

    // WinMain etc. omitted for brevity.

    extern (Windows) LPARAM wndProc(HWND hWnd, UINT uMsg, WPARAM 
 wParam, LPARAM lParam) {
        switch (uMsg) {

            case WM_CREATE:
                HWND comboBoxHandle = CreateWindowExA(0, 
 "COMBOBOX", "", WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | 
 CBS_HASSTRINGS, 10, 10, 150, 24, hWnd, null, null, null);
                SendMessageA(comboBoxHandle, CB_ADDSTRING, 0, 
 cast(LPARAM)toStringz("Item one"));
                SendMessageA(comboBoxHandle, CB_ADDSTRING, 0, 
 cast(LPARAM)toStringz("Item two"));

                break;

            default:
                break;
        }
        return DefWindowProcA(hWnd, uMsg, wParam, lParam);
    }

    void createMainWindow() {
        InitCommonControls();

        char[] className = "TestWindowClass";

        WNDCLASSA wc; // makes no difference if this is zero'd 
 out or not
        wc.lpfnWndProc = &wndProc;
        wc.lpszClassName = toStringz(className);
        wc.hInstance = GetModuleHandleA(null);
        RegisterClassA(&wc);

        HWND mainWindowHandle = CreateWindowExA(0, 
 toStringz(className), "", WS_OVERLAPPEDWINDOW, 0, 0, 500, 500, 
 null, null, null, null);
        ShowWindow(mainWindowHandle, SW_SHOW);
    }







Feb 26 2005
prev sibling next sibling parent "Ben Hinkle" <ben.hinkle gmail.com> writes:
That is odd. The same thing is happening with MinWin.

If I add a case for WM_LBUTTONDOWN to SetFocus(hWnd) it works but why the 
combo box isn't losing focus with the D version but it is with the C version 
I don't know. If you figure it out post the result so I can fix MinWin, too. 
I'll poke around, too, tomorrow if you haven't fixed it by then.

-Ben

"John C" <johnch_atms hotmail.com> wrote in message 
news:cvpnnq$4m3$1 digitaldaemon.com...
 You're right, the DialogBoxParam route is common, too. I'll try that later 
 today, but in the meantime here's the complete program. To repro: push the 
 combo box arrow to display the dropdown, and then click in the parent's 
 client area; the dropdown list remains visible, whereas it should get 
 dismissed.

 Command line: dmd testapp -debug -g -inline -L/EXET:NT -L/SU:windows 
 comctl32.lib

 module testapp;

 import std.string;
 import std.c.windows.windows;

 extern (C) void gc_init();
 extern (C) void gc_term();
 extern (C) void _minit();
 extern (C) void _moduleCtor();

 extern (Windows) void InitCommonControls();
 extern (Windows) BOOL IsDialogMessageA(HWND, MSG*);

 const int CBS_DROPDOWN = 0x0002;
 const int CBS_HASSTRINGS = 0x0200;
 const uint CB_ADDSTRING = 0x0143;

 HWND mainWindowHandle;

 extern (Windows) LPARAM wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, 
 LPARAM lParam) {
  switch (uMsg) {

    case WM_DESTROY:
      PostQuitMessage(0);
      break;

    case WM_CREATE:
      HWND comboBoxHandle = CreateWindowExA(0, "COMBOBOX", "", WS_CHILD | 
 WS_VISIBLE | CBS_DROPDOWN | CBS_HASSTRINGS, 10, 10, 150, 100, hWnd, null, 
 null, null);
      SendMessageA(comboBoxHandle, CB_ADDSTRING, 0, 
 cast(LPARAM)toStringz("Item one"));
      SendMessageA(comboBoxHandle, CB_ADDSTRING, 0, 
 cast(LPARAM)toStringz("Item two"));
      break;

    default:
      break;
  }
  return DefWindowProcA(hWnd, uMsg, wParam, lParam);
 }

 void createMainWindow() {
  InitCommonControls();

  char[] className = "TestWindowClass";

  WNDCLASSA wc;
  ((ubyte*)&wc)[0 .. wc.sizeof] = 0;
  wc.lpfnWndProc = &wndProc;
  wc.hCursor = LoadCursorA(null, IDC_ARROW);
  wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
  wc.lpfnWndProc = &wndProc;
  wc.lpszClassName = toStringz(className);
  wc.hInstance = GetModuleHandleA(null);
  RegisterClassA(&wc);

  mainWindowHandle = CreateWindowExA(0, toStringz(className), "", 
 WS_OVERLAPPEDWINDOW, 0, 0, 500, 500, null, null, null, null);
  ShowWindow(mainWindowHandle, SW_SHOW);
 }

 int main() {
  createMainWindow();
  MSG msg;
  while (GetMessageA(&msg, null, 0, 0)) {
    if (!IsDialogMessageA(mainWindowHandle, &msg)) {
      TranslateMessage(&msg);
      DispatchMessageA(&msg);
    }
  }
  return msg.wParam;
 }

 extern (Windows) int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
 LPSTR lpCmdLine, int nCmdShow) {
  int result = 0;
  gc_init();
  _minit();
  try {
    _moduleCtor();
    result = main();
  }
  catch (Object o) {
    result = 0;
  }
  gc_term();
  return result;
 }

 "Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message 
 news:cvpkpq$29q$1 digitaldaemon.com...
 Well, I stand by what I've said. The dialog manager is one of the oldest 
 parts of Windows, and one of the most widely understood.

 I suspect there's a subtle bug in your D implementation, and suggest you 
 post the full code.

 "John C" <johnch_atms hotmail.com> wrote in message 
 news:cvpjb9$1bs$1 digitaldaemon.com...
 Thanks for the suggestion. Generally an application's main window is 
 modeless, and using the GetMessage mechanism is fairly common. Adding 
 IsDialogMessage doesn't fix the issue with the child control's 
 behaviour, however.

 I've tested this on a few Windows machines, all exhibiting the same 
 problem. I tried out one of the other GUI libraries (DFL 
 http://www.dprogramming.com/dfl.php) and it shares this peculiarity.

 What's bizarre is that the same program works correctly when written in 
 C/C++, and I'm beginning to suspect that the D compiler is somehow 
 producing buggy executables. If I substitute the combo box with other 
 common controls in the same code I posted - list box, button, treeview - 
 everything's fine. So annoying that one control (which I plan to use in 
 quite a few places in my application) is misbehaving.

 "Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message 
 news:cvpg0u$3082$1 digitaldaemon.com...
 No, the dialog manager is an internal component to Windows that is 
 accessed by DialogBox or DialogBoxParam.

 What you've done is effectively create a modeless dialog, for which 
 you'd have to dispatch the dialog messages yourself. This can be done 
 by using IsDialogMessage() as in:

    while(GetMessage( . . . ))
    {
        if(!IsDialogMessage(mainWindowHandle, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

 But you're generally better off using DialogBoxParam()




 "John C" <johnch_atms hotmail.com> wrote in message 
 news:cvpemd$2s4p$1 digitaldaemon.com...
 Do you mean message pump? I do set that up with GetMessage, et al (I 
 just didn't include it in my post).

 "Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message 
 news:cvof52$1te3$1 digitaldaemon.com...
 There's no dialog manager!


 "John C" <johnch_atms hotmail.com> wrote in message 
 news:cvob5f$1q0o$1 digitaldaemon.com...
 Hi

 I'm struggling to see why the following code results in odd 
 behaviour on Windows XP SP2. It creates a main window and a combo 
 box, but the combo box's dropdown doesn't react correctly to mouse 
 clicks - it should disappear when the parent window is clicked, but 
 it remains visible until the parent loses the focus. Items in the 
 dropdown should also get highlighted as the mouse moves over it, but 
 don't.

 The equivalent code in C++, almost identical, works perfectly. I'd 
 be grateful if someone could diagnose what's going on. No exceptions 
 are thrown, and error checking reveals nothing weird.

 Cheers.

    import std.c.windows.windows;

    // WinMain etc. omitted for brevity.

    extern (Windows) LPARAM wndProc(HWND hWnd, UINT uMsg, WPARAM 
 wParam, LPARAM lParam) {
        switch (uMsg) {

            case WM_CREATE:
                HWND comboBoxHandle = CreateWindowExA(0, "COMBOBOX", 
 "", WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | CBS_HASSTRINGS, 10, 10, 
 150, 24, hWnd, null, null, null);
                SendMessageA(comboBoxHandle, CB_ADDSTRING, 0, 
 cast(LPARAM)toStringz("Item one"));
                SendMessageA(comboBoxHandle, CB_ADDSTRING, 0, 
 cast(LPARAM)toStringz("Item two"));

                break;

            default:
                break;
        }
        return DefWindowProcA(hWnd, uMsg, wParam, lParam);
    }

    void createMainWindow() {
        InitCommonControls();

        char[] className = "TestWindowClass";

        WNDCLASSA wc; // makes no difference if this is zero'd out or 
 not
        wc.lpfnWndProc = &wndProc;
        wc.lpszClassName = toStringz(className);
        wc.hInstance = GetModuleHandleA(null);
        RegisterClassA(&wc);

        HWND mainWindowHandle = CreateWindowExA(0, 
 toStringz(className), "", WS_OVERLAPPEDWINDOW, 0, 0, 500, 500, null, 
 null, null, null);
        ShowWindow(mainWindowHandle, SW_SHOW);
    }







Feb 26 2005
prev sibling parent reply Russell Wilkins <Russell.Wilkins grovestarsoftware.com> writes:
Create a testapp.def containing the following:

EXETYPE NT
SUBSYSTEM WINDOWS,4.0

compile: dmd testapp -debug -g -inline testapp.def

and you get  3d window where the combo box works as expected.

The command line doesn't allow passing windows,4.0 to the linker.  Use 
,5.0 for win xp.


Russell



John C wrote:
 You're right, the DialogBoxParam route is common, too. I'll try that later 
 today, but in the meantime here's the complete program. To repro: push the 
 combo box arrow to display the dropdown, and then click in the parent's 
 client area; the dropdown list remains visible, whereas it should get 
 dismissed.
 
 Command line: dmd testapp -debug -g -inline -L/EXET:NT -L/SU:windows 
 comctl32.lib
 
 module testapp;
 
 import std.string;
 import std.c.windows.windows;
 
 extern (C) void gc_init();
 extern (C) void gc_term();
 extern (C) void _minit();
 extern (C) void _moduleCtor();
 
 extern (Windows) void InitCommonControls();
 extern (Windows) BOOL IsDialogMessageA(HWND, MSG*);
 
 const int CBS_DROPDOWN = 0x0002;
 const int CBS_HASSTRINGS = 0x0200;
 const uint CB_ADDSTRING = 0x0143;
 
 HWND mainWindowHandle;
 
 extern (Windows) LPARAM wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM 
 lParam) {
   switch (uMsg) {
 
     case WM_DESTROY:
       PostQuitMessage(0);
       break;
 
     case WM_CREATE:
       HWND comboBoxHandle = CreateWindowExA(0, "COMBOBOX", "", WS_CHILD | 
 WS_VISIBLE | CBS_DROPDOWN | CBS_HASSTRINGS, 10, 10, 150, 100, hWnd, null, 
 null, null);
       SendMessageA(comboBoxHandle, CB_ADDSTRING, 0, 
 cast(LPARAM)toStringz("Item one"));
       SendMessageA(comboBoxHandle, CB_ADDSTRING, 0, 
 cast(LPARAM)toStringz("Item two"));
       break;
 
     default:
       break;
   }
   return DefWindowProcA(hWnd, uMsg, wParam, lParam);
 }
 
 void createMainWindow() {
   InitCommonControls();
 
   char[] className = "TestWindowClass";
 
   WNDCLASSA wc;
   ((ubyte*)&wc)[0 .. wc.sizeof] = 0;
   wc.lpfnWndProc = &wndProc;
   wc.hCursor = LoadCursorA(null, IDC_ARROW);
   wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
   wc.lpfnWndProc = &wndProc;
   wc.lpszClassName = toStringz(className);
   wc.hInstance = GetModuleHandleA(null);
   RegisterClassA(&wc);
 
   mainWindowHandle = CreateWindowExA(0, toStringz(className), "", 
 WS_OVERLAPPEDWINDOW, 0, 0, 500, 500, null, null, null, null);
   ShowWindow(mainWindowHandle, SW_SHOW);
 }
 
 int main() {
   createMainWindow();
   MSG msg;
   while (GetMessageA(&msg, null, 0, 0)) {
     if (!IsDialogMessageA(mainWindowHandle, &msg)) {
       TranslateMessage(&msg);
       DispatchMessageA(&msg);
     }
   }
   return msg.wParam;
 }
 
 extern (Windows) int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
 LPSTR lpCmdLine, int nCmdShow) {
   int result = 0;
   gc_init();
   _minit();
   try {
     _moduleCtor();
     result = main();
   }
   catch (Object o) {
     result = 0;
   }
   gc_term();
   return result;
 }
 
 "Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message 
 news:cvpkpq$29q$1 digitaldaemon.com...
 
Well, I stand by what I've said. The dialog manager is one of the oldest 
parts of Windows, and one of the most widely understood.

I suspect there's a subtle bug in your D implementation, and suggest you 
post the full code.

"John C" <johnch_atms hotmail.com> wrote in message 
news:cvpjb9$1bs$1 digitaldaemon.com...

Thanks for the suggestion. Generally an application's main window is 
modeless, and using the GetMessage mechanism is fairly common. Adding 
IsDialogMessage doesn't fix the issue with the child control's behaviour, 
however.

I've tested this on a few Windows machines, all exhibiting the same 
problem. I tried out one of the other GUI libraries (DFL 
http://www.dprogramming.com/dfl.php) and it shares this peculiarity.

What's bizarre is that the same program works correctly when written in 
C/C++, and I'm beginning to suspect that the D compiler is somehow 
producing buggy executables. If I substitute the combo box with other 
common controls in the same code I posted - list box, button, treeview - 
everything's fine. So annoying that one control (which I plan to use in 
quite a few places in my application) is misbehaving.

"Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message 
news:cvpg0u$3082$1 digitaldaemon.com...

No, the dialog manager is an internal component to Windows that is 
accessed by DialogBox or DialogBoxParam.

What you've done is effectively create a modeless dialog, for which 
you'd have to dispatch the dialog messages yourself. This can be done by 
using IsDialogMessage() as in:

   while(GetMessage( . . . ))
   {
       if(!IsDialogMessage(mainWindowHandle, &msg))
       {
           TranslateMessage(&msg);
           DispatchMessage(&msg);
       }
   }

But you're generally better off using DialogBoxParam()




"John C" <johnch_atms hotmail.com> wrote in message 
news:cvpemd$2s4p$1 digitaldaemon.com...

Do you mean message pump? I do set that up with GetMessage, et al (I 
just didn't include it in my post).

"Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message 
news:cvof52$1te3$1 digitaldaemon.com...

There's no dialog manager!


"John C" <johnch_atms hotmail.com> wrote in message 
news:cvob5f$1q0o$1 digitaldaemon.com...

Hi

I'm struggling to see why the following code results in odd behaviour 
on Windows XP SP2. It creates a main window and a combo box, but the 
combo box's dropdown doesn't react correctly to mouse clicks - it 
should disappear when the parent window is clicked, but it remains 
visible until the parent loses the focus. Items in the dropdown 
should also get highlighted as the mouse moves over it, but don't.

The equivalent code in C++, almost identical, works perfectly. I'd be 
grateful if someone could diagnose what's going on. No exceptions are 
thrown, and error checking reveals nothing weird.

Cheers.

   import std.c.windows.windows;

   // WinMain etc. omitted for brevity.

   extern (Windows) LPARAM wndProc(HWND hWnd, UINT uMsg, WPARAM 
wParam, LPARAM lParam) {
       switch (uMsg) {

           case WM_CREATE:
               HWND comboBoxHandle = CreateWindowExA(0, "COMBOBOX", 
"", WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | CBS_HASSTRINGS, 10, 10, 
150, 24, hWnd, null, null, null);
               SendMessageA(comboBoxHandle, CB_ADDSTRING, 0, 
cast(LPARAM)toStringz("Item one"));
               SendMessageA(comboBoxHandle, CB_ADDSTRING, 0, 
cast(LPARAM)toStringz("Item two"));

               break;

           default:
               break;
       }
       return DefWindowProcA(hWnd, uMsg, wParam, lParam);
   }

   void createMainWindow() {
       InitCommonControls();

       char[] className = "TestWindowClass";

       WNDCLASSA wc; // makes no difference if this is zero'd out or 
not
       wc.lpfnWndProc = &wndProc;
       wc.lpszClassName = toStringz(className);
       wc.hInstance = GetModuleHandleA(null);
       RegisterClassA(&wc);

       HWND mainWindowHandle = CreateWindowExA(0, 
toStringz(className), "", WS_OVERLAPPEDWINDOW, 0, 0, 500, 500, null, 
null, null, null);
       ShowWindow(mainWindowHandle, SW_SHOW);
   }







Feb 26 2005
next sibling parent "John C" <johnch_atms hotmail.com> writes:
Eureka. That fixed it. Russell, thanks so much. Matthew, I appreciate the 
time spent on this (DialogBoxParam didn't solve all the problems). I guess 
my C++ compiler does this automatically.

John.

"Russell Wilkins" <Russell.Wilkins grovestarsoftware.com> wrote in message 
news:cvpqml$7hh$1 digitaldaemon.com...
 Create a testapp.def containing the following:

 EXETYPE NT
 SUBSYSTEM WINDOWS,4.0

 compile: dmd testapp -debug -g -inline testapp.def

 and you get  3d window where the combo box works as expected.

 The command line doesn't allow passing windows,4.0 to the linker.  Use 
 ,5.0 for win xp.


 Russell



 John C wrote:
 You're right, the DialogBoxParam route is common, too. I'll try that 
 later today, but in the meantime here's the complete program. To repro: 
 push the combo box arrow to display the dropdown, and then click in the 
 parent's client area; the dropdown list remains visible, whereas it 
 should get dismissed.

 Command line: dmd testapp -debug -g -inline -L/EXET:NT -L/SU:windows 
 comctl32.lib

 module testapp;

 import std.string;
 import std.c.windows.windows;

 extern (C) void gc_init();
 extern (C) void gc_term();
 extern (C) void _minit();
 extern (C) void _moduleCtor();

 extern (Windows) void InitCommonControls();
 extern (Windows) BOOL IsDialogMessageA(HWND, MSG*);

 const int CBS_DROPDOWN = 0x0002;
 const int CBS_HASSTRINGS = 0x0200;
 const uint CB_ADDSTRING = 0x0143;

 HWND mainWindowHandle;

 extern (Windows) LPARAM wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, 
 LPARAM lParam) {
   switch (uMsg) {

     case WM_DESTROY:
       PostQuitMessage(0);
       break;

     case WM_CREATE:
       HWND comboBoxHandle = CreateWindowExA(0, "COMBOBOX", "", WS_CHILD | 
 WS_VISIBLE | CBS_DROPDOWN | CBS_HASSTRINGS, 10, 10, 150, 100, hWnd, null, 
 null, null);
       SendMessageA(comboBoxHandle, CB_ADDSTRING, 0, 
 cast(LPARAM)toStringz("Item one"));
       SendMessageA(comboBoxHandle, CB_ADDSTRING, 0, 
 cast(LPARAM)toStringz("Item two"));
       break;

     default:
       break;
   }
   return DefWindowProcA(hWnd, uMsg, wParam, lParam);
 }

 void createMainWindow() {
   InitCommonControls();

   char[] className = "TestWindowClass";

   WNDCLASSA wc;
   ((ubyte*)&wc)[0 .. wc.sizeof] = 0;
   wc.lpfnWndProc = &wndProc;
   wc.hCursor = LoadCursorA(null, IDC_ARROW);
   wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
   wc.lpfnWndProc = &wndProc;
   wc.lpszClassName = toStringz(className);
   wc.hInstance = GetModuleHandleA(null);
   RegisterClassA(&wc);

   mainWindowHandle = CreateWindowExA(0, toStringz(className), "", 
 WS_OVERLAPPEDWINDOW, 0, 0, 500, 500, null, null, null, null);
   ShowWindow(mainWindowHandle, SW_SHOW);
 }

 int main() {
   createMainWindow();
   MSG msg;
   while (GetMessageA(&msg, null, 0, 0)) {
     if (!IsDialogMessageA(mainWindowHandle, &msg)) {
       TranslateMessage(&msg);
       DispatchMessageA(&msg);
     }
   }
   return msg.wParam;
 }

 extern (Windows) int WinMain(HINSTANCE hInstance, HINSTANCE 
 hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
   int result = 0;
   gc_init();
   _minit();
   try {
     _moduleCtor();
     result = main();
   }
   catch (Object o) {
     result = 0;
   }
   gc_term();
   return result;
 }

 "Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message 
 news:cvpkpq$29q$1 digitaldaemon.com...

Well, I stand by what I've said. The dialog manager is one of the oldest 
parts of Windows, and one of the most widely understood.

I suspect there's a subtle bug in your D implementation, and suggest you 
post the full code.

"John C" <johnch_atms hotmail.com> wrote in message 
news:cvpjb9$1bs$1 digitaldaemon.com...

Thanks for the suggestion. Generally an application's main window is 
modeless, and using the GetMessage mechanism is fairly common. Adding 
IsDialogMessage doesn't fix the issue with the child control's 
behaviour, however.

I've tested this on a few Windows machines, all exhibiting the same 
problem. I tried out one of the other GUI libraries (DFL 
http://www.dprogramming.com/dfl.php) and it shares this peculiarity.

What's bizarre is that the same program works correctly when written in 
C/C++, and I'm beginning to suspect that the D compiler is somehow 
producing buggy executables. If I substitute the combo box with other 
common controls in the same code I posted - list box, button, treeview - 
everything's fine. So annoying that one control (which I plan to use in 
quite a few places in my application) is misbehaving.

"Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message 
news:cvpg0u$3082$1 digitaldaemon.com...

No, the dialog manager is an internal component to Windows that is 
accessed by DialogBox or DialogBoxParam.

What you've done is effectively create a modeless dialog, for which 
you'd have to dispatch the dialog messages yourself. This can be done 
by using IsDialogMessage() as in:

   while(GetMessage( . . . ))
   {
       if(!IsDialogMessage(mainWindowHandle, &msg))
       {
           TranslateMessage(&msg);
           DispatchMessage(&msg);
       }
   }

But you're generally better off using DialogBoxParam()




"John C" <johnch_atms hotmail.com> wrote in message 
news:cvpemd$2s4p$1 digitaldaemon.com...

Do you mean message pump? I do set that up with GetMessage, et al (I 
just didn't include it in my post).

"Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message 
news:cvof52$1te3$1 digitaldaemon.com...

There's no dialog manager!


"John C" <johnch_atms hotmail.com> wrote in message 
news:cvob5f$1q0o$1 digitaldaemon.com...

Hi

I'm struggling to see why the following code results in odd 
behaviour on Windows XP SP2. It creates a main window and a combo 
box, but the combo box's dropdown doesn't react correctly to mouse 
clicks - it should disappear when the parent window is clicked, but 
it remains visible until the parent loses the focus. Items in the 
dropdown should also get highlighted as the mouse moves over it, but 
don't.

The equivalent code in C++, almost identical, works perfectly. I'd 
be grateful if someone could diagnose what's going on. No exceptions 
are thrown, and error checking reveals nothing weird.

Cheers.

   import std.c.windows.windows;

   // WinMain etc. omitted for brevity.

   extern (Windows) LPARAM wndProc(HWND hWnd, UINT uMsg, WPARAM 
 wParam, LPARAM lParam) {
       switch (uMsg) {

           case WM_CREATE:
               HWND comboBoxHandle = CreateWindowExA(0, "COMBOBOX", 
 "", WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | CBS_HASSTRINGS, 10, 10, 
 150, 24, hWnd, null, null, null);
               SendMessageA(comboBoxHandle, CB_ADDSTRING, 0, 
 cast(LPARAM)toStringz("Item one"));
               SendMessageA(comboBoxHandle, CB_ADDSTRING, 0, 
 cast(LPARAM)toStringz("Item two"));

               break;

           default:
               break;
       }
       return DefWindowProcA(hWnd, uMsg, wParam, lParam);
   }

   void createMainWindow() {
       InitCommonControls();

       char[] className = "TestWindowClass";

       WNDCLASSA wc; // makes no difference if this is zero'd out or 
 not
       wc.lpfnWndProc = &wndProc;
       wc.lpszClassName = toStringz(className);
       wc.hInstance = GetModuleHandleA(null);
       RegisterClassA(&wc);

       HWND mainWindowHandle = CreateWindowExA(0, 
 toStringz(className), "", WS_OVERLAPPEDWINDOW, 0, 0, 500, 500, 
 null, null, null, null);
       ShowWindow(mainWindowHandle, SW_SHOW);
   }








Feb 26 2005
prev sibling parent Derek <derek psych.ward> writes:
On Sat, 26 Feb 2005 12:40:52 +0000, Russell Wilkins wrote:

 Create a testapp.def containing the following:
 
 EXETYPE NT
 SUBSYSTEM WINDOWS,4.0
 
 compile: dmd testapp -debug -g -inline testapp.def
 
 and you get  3d window where the combo box works as expected.
 
 The command line doesn't allow passing windows,4.0 to the linker.  Use 
 ,5.0 for win xp.
 

Not really wanting to self-promote, but my build utility does this for you if it detects that its a Windows application being built. However, it just uses the "SUBSYSTEM WINDOWS" without the exact Windows version number. I'll improve this soon. -- Derek Melbourne, Australia
Feb 26 2005