さっき決めたブログ

[Nim]デスクトップアプリを制作(Windows編)

Nimを使ってデスクトップアプリケーションの作成にチャレンジします!!!

Win32APIも使えるのでそれで1から素組という技もありますが、さすがにそれではきつい💦
なので、良いライブラリがないか探したところ、NiGuiというライブラリが良さげなので、そちらを使って開発していきます。
(nimxというのも試したのですが、こちらは起動時にWARNINGが出るなどいまいちだったので、こちらにしました)

Nimの環境設定に関しては、前の記事 プログラミング言語[Nim]を始めてみた を参照してみてください。

NiGuiのインストール

コンソールを起動して以下のコマンドを入力
nimble install nigui

"No local packages.json found, download it from internet? [y/N]" と聞かれるので、Yを入力

以上です。

基本的なプログラムの起動

基本的なWindowを表示するプログラムを作成します。

フォルダ D:\Projects\nim\nimtest02 を作成した後、VSCodeを起動フォルダを開きます

tasks.jsonの設定

VSCodeからフォルダを開き、メニューより ターミナルタスクの構成... を選択すると、
tasks.json ファイルが開くので、以下を入力します。

前回のHelloWordプログラムとの違いは、commandに --app:gui --threads:on を追加している点になります。

launch.jsonの設定

メニューより 実行構成の編集 を選択する。
launch.json ファイルが開くので、以下を入力

こちらの変更点は、programの名称のみで、他に違いはないです。

サンプルコード

ただ空のWindowを表示するだけのプログラムを作成してみます。

Ctrl+Shift+B でコンパイル。
F5で実行

こんな感じで空のWindowが表示されました。
実行結果

リソースの埋込

次にアプリケーションのアイコンやファイル情報をリソースファイルを用いて埋め込みます。
リソースは ResEdit などのリソースファイル編集ツールを使用して作成します。

アイコンは ICON HOI HOIさんのサイトから拝借させて頂いた.PNGファイルを、マルチアイコン作成を使用して.ICOファイル化し、icon.ico のファイル名で保存しておきました。
マニュフェストも作成しておきます。

app.manifest ファイルに以下を記載して保存しておきます。

コンソールより次のコマンドを入力して、nimtest02.res を作成します。
windres --input-format=rc --output-format=coff -o nimtest02.res nimtest02.rc

作成したリソースファイルをリンク時に取り込むように、tasks.json を修正します。

6行目に "--passL:nimtest02.res" を追加しています。
これでコンパイルを行うとアイコンとファイル情報が設定されているかと思います。

ファイル情報

ただし、これだとマニュフェストがうまく反映されていないようです。
(高解像度の端末で起動するとわかるのですが、dpiAware の設定が反映されていないようです)
いろいろ調べたら、NiGUI自体も、[ユーザフォルダ]\.nimble\pkgs\nigui-0.2.4\nigui\private\windows\manifest_x64.res にマニュフェストを組み込んだリソースファイルを持っていて、そちらの内容が優先されてしまっているようです。

どうにか回避方法は無いのか考えたのですが、本当はやりたくないけど、NiGuiのソースをいじってこちらのリソースの取り込みを無効化するしか無いようです(他に良い回避方法を知っている方教えて下さい)。

リソースは、[ユーザフォルダ]\.nimble\pkgs\nigui-0.2.4\nigui\private\windows\platform_impl.nim で取り込んでいますので、そちらを修正します。

上記ソースの14~17行目をコメントアウトすることで、マニュフェストの設定内容が反映されるようになりました。

ウインドウにアイコンを設定する

ウインドウのアイコンを先程リソースに組み込んだものにしてみます。

NiGuiの場合、Win.iconPath = [ファイル名] のように書けば、アイコンを設定できるようなのですが、それだと実行ファイルとは別にアイコンファイルを常に用意して置かなくてはならないので、先程作成したリソースの中に埋め込んだアイコンを使用できるようにします。

自分が調べた限りでは、NiGuiの機能ではiconPath以外で、ウインドウのアイコンを設定する方法はなさそう。
なので、Win32APIを使用して設定するしかなさそうです。
マルチプラットフォームではなくなってしまいますが、他のプラットフォームへの対応は今後やりたいとは考えてはいますが、その時に考える事に。

ここでまた問題が発生しました。

Win32APIを使用してウインドウを操作する場合ウインドウハンドル(HWnd)が必要になりますが、NiGUIのnewWindowで作成したウインドウの場合、HWndを取得できません(私の理解が足りないだけかもしれませんが、もし間違っていたら教えてください)。
ソースをちらっと読んだら、WindowImplクラスに一応fHandleって名前でハンドルを保存しているみたいなのですが、Privateなんですよね。。。

なので、仕方ないので再び最終手段。
本当の本当にやりたくないけど、NiGuiのソースをいじって、fHandleをPublicに変更します。
修正するのは、[ユーザフォルダ]\.nimble\pkgs\nigui-x.x.4\nigui\private\windows\platform_types1.nim になります。

修正したのは上記ソースの9,14行目に"*"を追加したところです。
非常に汚いやり方ですが、これでとりあえず自分のソースからfHandleを呼べるようになります。

コントロールを配置してみる

次にコントロールを配置してみます。
色々といじりながら適当に配置してみます。

起動してみたのがこんな感じです。

実行結果

なるほど~ .NetのWPFで言うところのスタックパネルのみでレイアウトを構成していくようなイメージですね。

DockやGrid的なものがあった方が嬉しいけど、これはこれでアリかと思います。
不満を言うと、標準で用意されているヴィジェット(コントロール)が少ないです。かなり少ないと思います。
タブとかスライダーとかイメージリストなんかも普通に用意してほしいところです。この辺りは今後増えていくような事がどっかに書いてあったので期待です。

あとはあまり細かい制御は出来ないよう。
色々凝りだすとやっぱりWin32APIを叩くことになるんですかね?

使ってみた感想

今回基本的な部分をいじってみたりして、非常に使いやすいものだという事は分かりました。
ただやはり初期バージョン故か、色々と細かい部分で残念なところもありましたです(自分が理解していないだけなのかもしれないが)。

  • 独自のマニュフェストが設定できない(今回は無理矢理設定した)
  • Windows Handleを取得できないので、Window操作系のWin32APIが使用できない(今回は無理矢理使用した)
  • 使えるヴィジェットの数が少ない

自分がWindows以外はほとんど知らないので、Windows特有の話が多いです。
クロスプラットフォームライブラリとしては対応し難いのかもしれないが、今後に期待したいところではあります。
なにはともあれ今後も色々と調べていこうと思います。

ここまでのコード

nimtest02.zip

参考にしたサイト

NiGui入門(v0.1.0)
https://qiita.com/tlllune/items/dc503802daf3df1789f4
リソースエディタResEditの使い方
http://gurigumi.s349.xrea.com/programming/visualcpp/resedit.html
ICON HOI HOI
http://iconhoihoi.oops.jp/
マルチアイコン作成
https://ao-system.net/multiicon/
Module windows(NimのWin32API定義一覧表)
https://nim-lang.org/0.11.0/windows.html

今回は以上となります。

投稿者プロフィール

KARASU
うーん いろいろ考え中。。。

コメント

コメント取得中...

関連記事

TOPへ