open-watcom / open-watcom-v2

Open Watcom V2.0 - Source code repository, Wiki, Latest Binary build, Archived builds including all installers for download.
Other
966 stars 157 forks source link

Impossible to "associate" an icon (defined into resource file) at an executable on Win 11 64 bit. #1335

Open tdechaize opened 23 hours ago

tdechaize commented 23 hours ago

Hi,

Just test an simply code to open a window on W11 (GUI application) with an icon defined into resource file. Normally, if I compile this example with GCC of MinGW64, list of files with used of Explorer see executable with "icon" screened. But, impossible with Open WATCOM V2, I spend many hours to test this, with different options (used "loadimage" in replacement of "loadicon"), nothing work.

Here these simply sources to test :

File main.cpp :

ifndef WIN32_LEAN_AND_MEAN

define WIN32_LEAN_AND_MEAN

endif

include

include "resource2.h"

// // // WndProc - Window procedure // // LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_DESTROY: ::PostQuitMessage(0); break; default: return ::DefWindowProc(hWnd, uMsg, wParam, lParam); }

return 0; }

// // // WinMain - Win32 application entry point. // // int APIENTRY wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd) { // Setup window class attributes. WNDCLASSEX wcex; ZeroMemory(&wcex, sizeof(wcex));

wcex.cbSize = sizeof(wcex); // WNDCLASSEX size in bytes wcex.style = CS_HREDRAW | CS_VREDRAW; // Window class styles wcex.lpszClassName = TEXT("MYFIRSTWINDOWCLASS"); // Window class name wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); // Window background brush color. // wcex.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON_1)); // Windows icon wcex.hIcon = (HICON)LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(IDI_ICON_1), IMAGE_ICON, 0, 0, LR_LOADTRANSPARENT); wcex.hCursor = LoadCursor(hInstance, IDC_ARROW); // Window cursor wcex.lpfnWndProc = WndProc; // Window procedure associated to this window class. wcex.hInstance = hInstance; // The application instance. // wcex.hIconSm = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON_1)); // Windows icon wcex.hIconSm = (HICON)LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(IDI_ICON_1), IMAGE_ICON, 0, 0, LR_LOADTRANSPARENT);

// Register window and ensure registration success. if (!RegisterClassEx(&wcex)) return 1;

// Setup window initialization attributes. CREATESTRUCT cs; ZeroMemory(&cs, sizeof(cs));

cs.x = 0; // Window X position cs.y = 0; // Window Y position cs.cx = 640; // Window width cs.cy = 480; // Window height cs.hInstance = hInstance; // Window instance. cs.lpszClass = wcex.lpszClassName; // Window class name cs.lpszName = TEXT("My First Window"); // Window title cs.style = WS_OVERLAPPEDWINDOW; // Window style

// Create the window. HWND hWnd = ::CreateWindowEx( cs.dwExStyle, cs.lpszClass, cs.lpszName, cs.style, cs.x, cs.y, cs.cx, cs.cy, cs.hwndParent, cs.hMenu, cs.hInstance, cs.lpCreateParams);

// Validate window. if (!hWnd) return 1;

// Display the window. ::ShowWindow(hWnd, SW_SHOWDEFAULT); ::UpdateWindow(hWnd);

// Main message loop. MSG msg; while (::GetMessage(&msg, hWnd, 0, 0) > 0) ::DispatchMessage(&msg);

// Unregister window class, freeing the memory that was // previously allocated for this window. ::UnregisterClass(wcex.lpszClassName, hInstance);

return (int)msg.wParam; }

File resource2.h :

ifndef HEADER_RESOURCE__INCLUDED

define HEADER_RESOURCE__INCLUDED

define IDI_ICON_1 102

define IDI_ICON_2 103

endif

File main.rc :

if defined(_WIN32) || defined(_WIN64)

include

include

include "resource2.h"

LANGUAGE LANG_FRENCH, SUBLANG_FRENCH

pragma code_page(1252)

//////////////////////////////////////////////////////////////////////////// // // Icon //

// Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. IDI_ICON_1 ICON "OpenGL.ico" IDI_ICON_2 ICON "OpenGL.ico"

endif

File to generate application with MinGW64 "generate_mingw64.bat" :

set PATHSAV=%PATH% set PATH=C:\mingw64\bin;%PATH% windres main.rc -O coff -o main.res g++ -o main.exe main.cpp main.res -Wl,-subsystem,windows -municode set PATH=%PATHSAV%

File to generate application with Open WATCOM V2 "generate_watcom.bat" :

set PATHSAV=%PATH% set PATH=C:\WATCOM\binnt;%PATH% wrc main.rc -r -bt=nt -iC:\WATCOM\h\nt -iC:\WATCOM\h -fomain.res wpp386 -bg -bt=nt main.cpp -IC:\WATCOM\h\nt -IC:\WATCOM\h wlink option quiet system nt_win LIBP C:\WATCOM\lib386\nt;C:\WATCOM\lib386 file main.obj option resource=main.res name main.exe library user32,kernel32 set PATH=%PATHSAV%

This two generations success, but only with GCC executable is "see" in Explorer with icon, not with OW 2.0.

Bug ?

Thank's.

jmalak commented 22 hours ago

First note is that Open Watcom create 32-bit application not 64-bit that in 64-bit application can be a little different rules. Second note if you look on standard Open Watcom tools (32-bit) with assigned icon you will see it properly in Windows Explorer. 64-bit version of tools is compiled by Visual Studio that it is not relevant for your case, but it is build from same source code. 64-bit version is also OK in Windows Explorer. OW is capable to do what you want but something is wrong that you didn't get correct result. I am not expert on Windows GUI programming that I can only look on similar case used in Open Watcom source code.

But what you describe has nothing to do with your code, but with resource records only. All our tools has required icon as first, with lowest ID.

It could be some issue with linker which bind your resource records to executable. Try to use Open Watcom resource compiler to add resource records to executable instead of linker. Use command wrc -q -k main.res main.exe

jmalak commented 22 hours ago

Sorry I was wrong the application icon is first icon in resources only not lowest ID. May be that linker is reordering icons resources. But wrc -k should not change it.

jmalak commented 21 hours ago

Anyway here is our code for register main class.

/*
 * RegisterMainWindow - register the main (root) window class
 */
bool RegisterMainWindow( HANDLE inst )
{
    WNDCLASS    wc;

    wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = GetWndProc( MainWindowProc );
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = inst;
    wc.hIcon = LoadIcon( inst, "APPLICON" );
    wc.hCursor = LoadCursor( (HINSTANCE)NULLHANDLE, IDC_ARROW );
    wc.hbrBackground = 0;
    wc.lpszMenuName = NULL;
    wc.lpszClassName = EditorName;
    return( RegisterClass( &wc ) != 0 );

} /* RegisterMainWindow */

it is code working on 16/32/64-bit Windows

tdechaize commented 2 hours ago

Ok, thank's for your response. I shall try today your proposition. I return after this test.

PS : Sorry, I don't join my test icon file, because format "*.ico" is not authorized by ... GitHub ...

tdechaize commented 2 hours ago

Test OK and without add your new proposed function. Pbm was in RC file with test "#if defined(_WIN32) || defined(_WIN64)" at the beginning, after suppress it all is "normal". 👍 Sorry, not an issue about OW32 on Win11. You can close it.

Bye.

jmalak commented 1 hour ago

No problem, good to know that no issue with OW.

tdechaize commented 9 minutes ago

Yes. In my mind, it's seem urgent to port OW 32 bit to "real" 64 bit on Window first (or maybe on Linux if much easy it ...). In future, all processors will be 64 (or 128 maybe) ... and layer "32 bit" like WoW on Windows will be dropped (unmaintained ??) ... not tomorrow, but some years after ...

I know, it's "long time and long work" to success, but otherwise OW 32 risk to be dropped also ... Today, it's interesting for old architecture (X86, 16 or 32 bits) and old systems (DOS, OS2, Netware, ...), and with x86-64 with "good" layer", but maybe it's only "niche market" (not applicable with "free" compilers ..-) ).

Sincerly.