simonkrauter / NiGui

Cross-platform desktop GUI toolkit written in Nim
MIT License
722 stars 51 forks source link

Windows: Error: Set default application context failed (OS Error Code: 14011) #29

Open mashingan opened 5 years ago

mashingan commented 5 years ago

When I tried to compile example_01_basic_app.nim , it gave me runtime error

platform_impl.nim(373)   init
platform_impl.nim(173)   pEnableVisualStyles
platform_impl.nim(32)    pRaiseLastOSError
nigui.nim(935)           raiseError
Error: unhandled exception: An attempt to set the process default activation context failed because the process default activation context was already set. (OS Error Code: 14011) [Exception]

I compiled with mingw64-gcc

gcc --version
gcc (Rev3, Built by MSYS2 project) 8.2.0

When I tried and ran using tcc, it's working fine

tcc -v
tcc version 0.9.27 (x86_64 Windows)

I'm on Windows 10 64-bit.

simonkrauter commented 5 years ago

It works for me with MinGW under Windows 10 64-bit. I will try to compile with MSYS2.

mashingan commented 5 years ago

Thanks for response.

I confirm I'm able to run it fine with mingw64. I installed mingw64 with SEH and win32 threading.

As gcc for MSYS2, the thread model is posix. I couldn't find whether its exception is SEH or sjlj.

simonkrauter commented 5 years ago

When I try to compile with MSYS2 GCC:

Error: execution of an external compiler program 'C:\msys64\mingw64\bin\gcc.exe -c  -w -mno-ms-bitfields -DWIN32_LEAN_AND_MEAN [...] stdlib_system.c' failed with exit code: 1
simonkrauter commented 5 years ago

This is not an issue of NiGui. Closing.

phanirithvij commented 4 years ago

How to resolve this? I tried nim c --app:gui NiCalc.nim and the build succeeds but the app upon opening gives this error.

simonkrauter commented 4 years ago

It seems there is an problem with the call of CreateActCtxA() in shell32.dll on some systems. Workaround I guess: Comment out pEnableVisualStyles() in src/nigui/private/windows/platform_impl.nim. To find out the reason: Did you compile the app to 32 or 64 bit?

simonkrauter commented 4 years ago

The reported error message appears when app.init() is called twice.

exelotl commented 4 years ago

Hey, I'm getting this same issue when running example_01_basic_app. I'm using MSYS2, the problem occurs regardless of whether I build with mingw32 or mingw64.

image

Commenting out the call to pEnableVisualStyles() does indeed fix things, but naturally this means I get the "Windows 95" UI.

image

One might call this a feature, but I'm not really feeling the retro aesthetic today ;)

From what I could find, the approach used by pEnableVisualStyles is a bit of a hack, not a recommended way of doing things. But I don't know much about the win32 API, not sure if there's some simple change that would make it work.

I was able to enable visual styles using a resource file:

resources.rc (where 1 is "executable", 24 is "resource type: manifest")

1 24 "Application.manifest"

Application.manifest (where the dependency tells Windows to load V6 of the common controls library)

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <dependency>
        <dependentAssembly>
            <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*" />
        </dependentAssembly>
    </dependency>
</assembly>

Then I compiled the resource with windres and passed it to the linker:

$ windres resources.rc -o resources.o
$ nim c --app:gui --passL:"resources.o" example_01_basic_app.nim
$ ./example_01_basic_app.exe

image

So yeah that works, but I guess it's not ideal because it's no longer a self contained solution. How would we solve this? One option could be to assume that windres exists and do some compile-time magic on when defined(windows) and defined(gcc), using staticExec and {.passL.}? Idk, seems like it makes a lot of assumptions. On the other hand, I believe there's a lot of other stuff that can be done with resource files, so it might be worth it in the long run...

It appears that this same thing could be achieved in MSVC with a C preprocessor pragma, but that's not very useful since I couldn't find anything similar that would work in MinGW GCC.

#pragma comment(linker,"\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

Regardless, it's also recommended to initialise the Common Controls library to prevent weirdness from occurring. One tutorial suggested to use ICC_WIN95_CLASSES, and another one suggested ICC_STANDARD_CLASSES, not really sure which flags are necessary here...

{.pragma: libComctl32, stdcall, dynlib: "Comctl32.dll".}

const
  ICC_WIN95_CLASSES* = 0x000000FF
  ICC_STANDARD_CLASSES* = 0x00004000

type InitCommonControlsExInfo* = object
  dwSize*, dwICC*: int32

proc InitCommonControlsEx*(picce: ptr InitCommonControlsExInfo): bool {.importc: "InitCommonControlsEx", libComctl32.}

proc pInitCommonControls() =
  var icc: InitCommonControlsExInfo
  icc.dwSize = sizeof(icc).int32
  icc.dwICC = ICC_WIN95_CLASSES or ICC_STANDARD_CLASSES
  discard InitCommonControlsEx(addr icc)

Anyways, I think a lot of Windows users will be running into these issues, so they should definitely be addressed. Let me know what you think about any of this stuff!

exelotl commented 4 years ago

Following up to this, I noticed that simply importing Winim in the project causes the correct visual styles to be applied.

Upon investigation it looks like they're doing something similar to what I suggested (see winimbase.nim) but using precompiled resources instead of doing any staticExec trickery.

I think adopting Winim as a dependency for this project, in place of the current minimal Win32 bindings, could be a good idea. The author has done some things really well (e.g. correct handling of wide char strings, with directives to toggle which kind of string to use)

simonkrauter commented 4 years ago

@exelotl Can you please create a new issue by giving detailed "steps to reproduce" including Windows version, how to install Nim, how to install MSYS2 and how to compile the example. I want to be able to reproduce the error.