www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - (WinAPI) FindWindowW always fails

reply Deen O'Connor <deen.oconnor yandex.ru> writes:
I was coding my project, and at some point it required to get 
widow rectangle. GetWindowRect function returned 
ERROR_INVALID_WINDOW_HANDLE (0x578) error. This is where i 
detected the error. I then checked what the return value of 
FindWindowW was, and it was 0. GetLastError showed that there was 
ERROR_NOT_ALL_ASSIGNED (0x514) error.

So, to re-create the error, i did the following:
1 - Opened an app that has a window. In my case this was x32dbg, 
i chose it because it has a short window name without any spaces.
2 - Wrote a small program to check if the error will happen again:
import std.stdio;
import std.conv;
import core.sys.windows.windows;

void main(string[] args) {
     wstring wndName = "x32dbg";
     HWND hWnd = FindWindowW(null, cast(wchar*)&wndName);
     if (hWnd is null) {
         writeln("Error 0x" ~ to!string(GetLastError(), 16) ~ " in 
FindWindowW()!");
     } else {
         writeln("x32dbg window: 0x" ~ to!string(cast(uint)hWnd, 
16));
     }
}
3 - Ran this code with rdmd

Output said that there was an error.
This also happened with every window i tried to find no matter 
what. FindWindowA also failed.

The only reason i'm writing this is because i can find the window 
with x32dbg and a very similar C++ code works fine.
So, am i doing something wrong, or is this a bug?
Oct 08 2020
next sibling parent reply Dennis <dkorpel gmail.com> writes:
On Thursday, 8 October 2020 at 19:39:05 UTC, Deen O'Connor wrote:
     wstring wndName = "x32dbg";
     HWND hWnd = FindWindowW(null, cast(wchar*)&wndName);
Dont take the address of the `wstring`, use `wndName.ptr` instead. wstring is internally a fat pointer that looks like this: struct wstring { size_t length; immutable(wchar)* ptr; } When taking the address `&wndName`, you get a pointer to this struct on the stack, not the actual string literal.
Oct 08 2020
parent Deen O'Connor <deen.oconnor yandex.ru> writes:
On Thursday, 8 October 2020 at 19:49:04 UTC, Dennis wrote:
 Dont take the address of the `wstring`, use `wndName.ptr` 
 instead.
It worked, thanks a lot!
Oct 08 2020
prev sibling next sibling parent =?UTF-8?B?0JLQuNGC0LDQu9C40Lkg0KTQsNC0?= =?UTF-8?B?0LXQtdCy?= writes:
On Thursday, 8 October 2020 at 19:39:05 UTC, Deen O'Connor wrote:
 I was coding my project, and at some point it required to get 
 widow rectangle. GetWindowRect function returned 
 ERROR_INVALID_WINDOW_HANDLE (0x578) error. This is where i 
 detected the error. I then checked what the return value of 
 FindWindowW was, and it was 0. GetLastError showed that there 
 was ERROR_NOT_ALL_ASSIGNED (0x514) error.

 So, to re-create the error, i did the following:
 1 - Opened an app that has a window. In my case this was 
 x32dbg, i chose it because it has a short window name without 
 any spaces.
 2 - Wrote a small program to check if the error will happen 
 again:
 import std.stdio;
 import std.conv;
 import core.sys.windows.windows;

 void main(string[] args) {
     wstring wndName = "x32dbg";
     HWND hWnd = FindWindowW(null, cast(wchar*)&wndName);
     if (hWnd is null) {
         writeln("Error 0x" ~ to!string(GetLastError(), 16) ~ " 
 in FindWindowW()!");
     } else {
         writeln("x32dbg window: 0x" ~ to!string(cast(uint)hWnd, 
 16));
     }
 }
 3 - Ran this code with rdmd

 Output said that there was an error.
 This also happened with every window i tried to find no matter 
 what. FindWindowA also failed.

 The only reason i'm writing this is because i can find the 
 window with x32dbg and a very similar C++ code works fine.
 So, am i doing something wrong, or is this a bug?
I using like this: HWND hwnd = FindWindow( "Window", "Panel" ); if ( hwnd ) { PostMessage( hwnd, APP_MAIN_MENU, 0, 0 ); }
     wstring wndName = "x32dbg";
     HWND hWnd = FindWindowW(null, cast(wchar*)&wndName);
I think some like this... LPCWSTR toLPCWSTR( string s ) nothrow // const wchar_t* { import std.utf : toUTFz, toUTF16z, UTFException; try { return toUTF16z( s ); } catch ( UTFException e ) { return "ERR"w.ptr; } catch ( Exception e ) { return "ERR"w.ptr; } } alias toLPCWSTR toPCWSTR; wstring wndName = "x32dbg"; HWND hWnd = FindWindowW( null, wndName.toLPCWSTR );
Oct 08 2020
prev sibling next sibling parent Bastiaan Veelo <Bastiaan Veelo.net> writes:
On Thursday, 8 October 2020 at 19:39:05 UTC, Deen O'Connor wrote:
     HWND hWnd = FindWindowW(null, cast(wchar*)&wndName);
...
 So, am i doing something wrong, or is this a bug?
You are taking the address of a slice and pass it as if it were a C string. You can use toUtf16z for a conversion, but do note the limitations of toUtfz. -Bastiaan PS this is more a subject for the Learn forum.
Oct 08 2020
prev sibling parent =?UTF-8?B?0JLQuNGC0LDQu9C40Lkg0KTQsNC0?= =?UTF-8?B?0LXQtdCy?= writes:
On Thursday, 8 October 2020 at 19:39:05 UTC, Deen O'Connor wrote:
 ...
 import std.stdio;
 import std.conv;
 import core.sys.windows.windows;

 void main(string[] args) {
     wstring wndName = "x32dbg";
     HWND hWnd = FindWindowW(null, cast(wchar*)&wndName);
     if (hWnd is null) {
         writeln("Error 0x" ~ to!string(GetLastError(), 16) ~ " 
 in FindWindowW()!");
     } else {
         writeln("x32dbg window: 0x" ~ to!string(cast(uint)hWnd, 
 16));
     }
 }
and may be you find interesting this construction: writefln( "x32dbg window: %X", hWnd );
Oct 08 2020