Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Contribution] How to use Crystal / WebView bindings without console : #23

Open
serge-hulne opened this issue Feb 17, 2023 · 4 comments

Comments

@serge-hulne
Copy link

serge-hulne commented Feb 17, 2023

#hide_console.cr
hide_console.cr

Source :

https://forum.crystal-lang.org/t/compilation-switch-to-avoid-the-debug-console-under-windows/5356/6

#Usage:

require "../webview"
require "./hide_console"

def runApp()
    wv = Webview.window(1500, 1000, Webview::SizeHints::NONE, "Hello WebView", "http://crystal-lang.org")
    wv.run
    wv.destroy
end

runApp()

#Code :

{% if flag? :windows %}
  module Crystal::System::FileDescriptor
    def self.from_stdio(fd)
      console_handle = false
      handle = LibC._get_osfhandle(fd)
      if handle != -1 && handle != -2
        handle = LibC::HANDLE.new(handle)
        # TODO: use `out old_mode` after implementing interpreter out closured var
        old_mode = uninitialized LibC::DWORD
        if LibC.GetConsoleMode(handle, pointerof(old_mode)) != 0
          console_handle = true
          if fd == 1 || fd == 2 # STDOUT or STDERR
            if LibC.SetConsoleMode(handle, old_mode | LibC::ENABLE_VIRTUAL_TERMINAL_PROCESSING) != 0
              at_exit { LibC.SetConsoleMode(handle, old_mode) }
            end
          end
        end
      end

      io = IO::FileDescriptor.new(fd, blocking: true)
      # Set sync or flush_on_newline as described in STDOUT and STDERR docs.
      # See https://crystal-lang.org/api/toplevel.html#STDERR
      if console_handle
        io.sync = true
      else
        io.flush_on_newline = true
      end
      io
    end
  end

  @[Link(ldflags: "/ENTRY:wWinMainCRTStartup")]
  @[Link(ldflags: "/SUBSYSTEM:WINDOWS")]
  lib LibCrystalMain
  end

  lib LibC
    fun CommandLineToArgvW(lpCmdLine : LPWSTR, pNumArgs : Int*) : LPWSTR*
    fun LocalFree(hMem : Void*) : Void*
  end

  fun wWinMain(
    hInstance : Void*,
    hPrevInstance : Void*,
    pCmdLine : LibC::LPWSTR,
    nCmdShow : LibC::Int
  ) : LibC::Int
    argv = LibC.CommandLineToArgvW(pCmdLine, out argc)
    wmain(argc, argv)
    ensure
      LibC.LocalFree(argv) if argv
  end
{% end %}
@naqvis
Copy link
Owner

naqvis commented Feb 18, 2023

Thanks @serge-hulne , but I don't think adding monkey patching to any shard is good option. Above cited issue is Crystal specific and i'm sure, future versions of Crystal will have that fixed.

@serge-hulne
Copy link
Author

serge-hulne commented Feb 18, 2023 via email

@lightswisp
Copy link

@serge-hulne
Hello there, you could try to use these methods from WinApi. (GetConsoleWindow) (ShowWindow)

Import it by:

@[Link("user32")]
lib WinApi
  fun GetConsoleWindow() : Int32*
  fun ShowWindow(handle : Int32*, ncmdshow : Int32)
end

Then invoke it like this:

handle = WinApi.GetConsoleWindow()
WinApi.ShowWindow(handle, 0)

The logic is following: get the handle via GetConsoleWindow, then pass the handle to the ShowWindow(handle, 0). Zero means, SW_HIDE.

Hope this helps!

@serge-hulne
Copy link
Author

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants