CreateWindowEx fails in 64 bit but not 32 bit


#1

In juce_win32_Windowing.cpp line 1168 I am getting a failure of CreateWindowEx in 64 bit WIndows 7 under Cubase 64 bit. The returned hwnd==0 which causes an assertion. There is no failure in 32 bit Windows 7. I inserted GetLastError() after the call and see a return code of 998 which is an invalid memory access error. Can anyone help?


#2

very strange! Doing some searching online, it sounds like some structures may have changed - could you try adding these tweaks to to WindowClassHolder constructor, and see if it helps (or if it asserts because the class registration is the bit that failing)?

[code] WNDCLASSEX wcex;
zerostruct (wcex);
wcex.cbSize = sizeof (wcex);
wcex.style = CS_OWNDC;
wcex.lpfnWndProc = (WNDPROC) windowProc;
wcex.lpszClassName = windowClassName.toWideCharPointer();
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 32;
wcex.hInstance = moduleHandle;
wcex.hIcon = ExtractAssociatedIcon (moduleHandle, moduleFile, &iconNum);
iconNum = 1;
wcex.hIconSm = ExtractAssociatedIcon (moduleHandle, moduleFile, &iconNum);
wcex.hCursor = 0;
wcex.hbrBackground = 0;
wcex.lpszMenuName = 0;

        ATOM result = RegisterClassEx (&wcex);
        (void) result;
        jassert (result != 0);
    }

[/code]


#3

Thanks, Jules for the quick response. Unfortunately, after incorporating the tweak the problem is the same. Return value is 998 after calling GetLastError(). I’m not sure how I would checking if the class registration is broken.


#4

That’s why I put the assertion in there - if it’s not firing then presumably the registration is ok.

Hmm, I really don’t know what else could be wrong with it… While I was looking at the code I noticed one minor thing that could be tidied up, so will check in a new version soon which you could try. (I doubt if it’ll fix it though)


#5

I am confused. In the previous posts I was compiling and linking to the 64 bit static library version of Juce. I decided to try the amalgamated version so I created a little amalgamated test app. Then when I compile that as Debug 64 bit I get a compile time error saying that String has no function called toWideCharPointer, a function that is called in the tweak you posted but is in fact missing from the version of String.h that I am using – downloaded from the Juce tip about one week ago. However, I do not get this compile time error when compiling the static library version. Why is that? What should I do?


#6

The confusion has been partially resolved but not the problem. I incorporated the tweak you gave and saved juce_win32_Windowing.cpp but did not Clean the entire library. Then juce_win32_Windowing.cpp appeared to recompile and the library was remade successfully. However in fact juce_win32_Windowing.cpp is only really recompiled through juce_win32_Native.cpp. So in fact I never really tried your tweak. However, I apparently cannot try it because of the aforementioned lack of the String::toWideCharPointer in this recent version of Juce.


#7

I added toWideCharPointer() about a week ago, so you’d need to be right up to date. There were a couple of things I spotted in the window class code that I wanted to clean up, so I’ll check in an update shortly - best plan is to wait for that and then try it again.


#8

Excellent! This new version did indeed solve the window creation problem. However, please see the new post on memory leaks in the AudioPlugins forum.


#9

Hi Jules, I have the same problem using VS2010 without Juice, may I know how to fix the following?

RegisterClass sucessful but fail to CreateWindowEx in 64 bit but not 32bit.

 


#10

If you're not using juce (and can't even spell it correctly!) then it's quite optimistic to expect this topic to be of any relevance to you..


#11

I see this is an old thread, but I recently encountered what sounds like the same problem when attempting to create a non-opaque window. While digging I noticed the following in the Windows docs:

WS_EX_LAYERED
0x00080000
The window is a layered window. This style cannot be used if the window has a class style of either CS_OWNDC or CS_CLASSDC.
Windows 8: The WS_EX_LAYERED style is supported for top-level windows and child windows. Previous Windows versions support WS_EX_LAYERED only for top-level windows.

Not sure if that’s what’s going on here, but it does seem like you could end up with this combination. In my case CreateWindowEx() returns a NULL hwnd and the winProc is called only once with a WM_NCDESTROY message.


#12

If it wasn’t possible to create transparent windows in 64-bit then I’d be amazed if we hadn’t already heard about it, or seen it ourselves in the demo apps or other things we’re working on! What exactly are you building where you’re seeing this happen?


#13

Thanks for the speedy reply. I am new to Juce and realized after I posted that this does seem somewhat impossible given that many components would get created in this way. I’m building 64 bit with VS2015, and I do see that many windows in myproject are created just fine in this way. So I’m not sure what’s specifically causing this. I will try to figure out what the X factor is and post again if I find it.


#14

The differences I see between successful/unsuccessful hwnd creations are:

SUCCESSFUL:
parentToAddTo is NULL.
type is WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_POPUP | WS_SYSMENU

UNSUCCESSFUL:
parentToAddTo is non-NULL.
type is WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_CHILD

exstyle in both cases is WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT.

** Edit:**
So the child window part is probably it. From the docs: “Note Beginning with Windows 8, WS_EX_LAYERED can be used with child windows and top-level windows. Previous Windows versions support WS_EX_LAYERED only for top-level windows.”. I’m on Windows 10 but I wonder if this is still biting because I’m using VS2015? In any case, going strictly by the MS docs, I don’t see why it’s legal to do CreateWindowEx() with WS_EX_LAYERED and CS_OWNDC, regardless of parentage or Windows version.


#15

OK… well as far as I know, nothing in JUCE should attemp to create a transparent child window, so am presuming that you’re doing something off-piste to get into this situation?


#16

Yes, it appears so. In addition to being new to Juce I am new to this code and did not realize all that was going on here.

It appears that in this case the componentParentHierarchyChanged() is being overridden to do something unusual. The code grabs the parent’s window_handle, removes the component from the desktop, sets itself to be non-visible, then re-adds itself to the desktop, passing ComponentPeer::windowIgnoresMouseClicks and the saved window_handle as arguments.

I believe this is an attempt to create a special view layer to which components can be attached without being part of the normal window region (in an attempt to speed up drawing).

In any case, it’s clearly not a normal use case. Sorry for wasting anyone’s time. I thought it was relevant to the discussion, but it seems like it’s not.


#17

OK, I see. Definitely very much an edge-case as far as we’re concerned, but if you find anything in there we could change which would make things work for you without affecting other existing code then we’re not averse to that!