河童さん

あれやそれ

データ共有アプリ

2023-09-21 20:27:58 | Rust

クリップボード共有アプリを作ったけど、実はあれ、当初考案したアプリを作れなかったので、無理くり作ったヤツだった。

 

当初は、リッチテキストに色々書いて、共有するのが目的だったんだけど、使用したwin32apiラッパーのクレートがリッチテキストの保存・読込みに対応してなかったので放棄した。

悩んだ末に、クリップボード共有アプリになったんだけど、やっぱり当初考えたアプリが気になるので、MS嫌いなのにwin32apiを調べ始める。

 

  • win32api

昔のapiだから、全部関数。

しかも、引数更新系。

うわ~、古っ。

データは、構造体で、引数として渡す。

処理は、対象ウィンドウ(コントロール)にメッセージ飛ばして、処理してもらう。

引数は2個決まってて、あらゆる変数をその引数にキャストして渡してる。

しかも、int を用途毎に別名作ってるので、一目で何に使うのか分かりやすいんだろうけど、何するにもキャストキャストキャスト。

うーん、全く勉強する気にならん。

 

  • クレート改造

とは言え、勉強しなきゃクレート改造も出来ないので、ちまちま勉強して、クレート改造に取り組む。

リッチテキスト自体は、導入されてて、機能は、書式設定のみ使える。

後は、保存と読み込みのメッセージを投げて、処理するようにすればよい。

メッセージ用の定数をヘッダファイル見つつ、追記。

保存・読込み用の構造体があるので、これもヘッダファイル見つつ、追記。

構造体のメンバにコールバック関数があるから、これも追記。

 

試しに動かしてみるが、当然動かないw

まぁ、そんな簡単に動くわけないよな。

win32apiのデータ型とRustのデータ型が違うので、コールバック関数に何設定すればいいのか、分からん。

更新引数はmut付ければいいのか?

Rustは生ポインタ使わないから、どう書けばいいのやら?(unsafe内なら使えるけど)

 

他のwin32apiのクレートを参照しつつ、書き換えていく。

データ型は、たぶんOKなんだが、ボタン押すとアプリが落ちる。

せめてコンソールにエラー出してくれぇぇぇ。

 

他のクレートを参照しまくって、見つけた!

同じような構造体定義にpackedを使ってた。

意味が分からんが、記載して、動かしたら、動いた!!

 

どうやら、メモリの空きを詰めるのがpackedらしい。

それだとC言語の想定しているメモリアドレスと違ってくるから、逆に落ちそうだけど、何故動くのか?

原因は分からんまま、動いたので、良しとする。

 

  • データ共有アプリ作成

win32apiラップクレート改が出来たので、さっそく当初想定したアプリを作る。

クリップボード共有アプリのソースをコピペしつつ、画面デザインしつつ、完成。

今回は、「転送」ボタン押すとリッチテキストファイルに保存。

タイマーで1秒毎にリッチテキストファイルの更新を監視して、更新されてたら、自動読込み。

ボタン1個になったので、手間が減った。

しかも、クリップボード共有アプリでは、実現できなかった、書式付テキスト、表を転送出来るようになった。

これで思いついたアプリを作る事が出来て満足~。

 

  • 画像の不具合

さっそく、別アプリ作ったよ~、と周知して、一人満足感に浸ってたら、画像が貼り付けできないと報告あり。

そういや転送される事しか確認してなかった。

転送後の画像をコピーして、Excelに張り付けたら、「Image」と文字列で張り付く。

うがぁぁぁぁ、そういやリッチテキストファイルって、全部文字列で保存していたな。

見た目画像なので、失念してた。

リッチテキストに対応している、ワードパッドとWordは、画像として貼り付けできるが、ExcelとTeamsにはImageと文字列で張り付く。

 

どうにもならんので、Excelには、形式指定貼り付けして。TeamsはExcelに張り付けた画像をコピペして、と対策案を提示。

 

コピーした文字列を画像に変換出来ればいいんだけど、どうやればいいのか、さっぱり分からん。

分かる方、教えて~。

 


クリップボード共有アプリ

2023-09-20 19:30:24 | Rust

久しぶりにRustでアプリ作った。

クリップボードを仮想端末間で共有するアプリだ。

 

  • 環境

仮想端末が2個。

仮想端末A→仮想端末Bへ接続。

間は、踏み台サーバあり。

A端末とB端末のデータ共有用サーバあり。

 

今までは、データ共有サーバにファイル作って、Aで更新し、Bで読込みして、取得、としていた(らしい)。

俺は、その環境で仕事してないので、聞いた話。

 

  • アプリ機能

データ共有用サーバがあるので、そこに共有データファイルを作成。

「転送」ボタン押すと、クリップボードの中身を共有データファイルへ上書き。

「取得」ボタン押すと、共有データファイルを読み込み、クリップボードへ設定。

 

自分でも使ってみたが、すっごい楽。

アプリ無しの環境で仕事してなかったけど、アプリ楽。

たまにしか仕事しない環境だけど、作って良かった。

 

  • GUI

GUIは、win32apiをラップしたクレートを使用。

人生初のwin32apiだ。

MS嫌いなので、避けて避けて避けて来た道。

とは言え、いい感じにRust風にラップしてくれてるので、Rust風に書けるから、win32api感は無い。

その代わりWindowsでしか使えないアプリになるけど、職場のPCは、全部Windowsなので問題ない。

 

  • 総評

Rustで初めてGUIアプリ作ったけど、なかなか楽しい。

やっぱり画面があるアプリって面白いな。

今までコマンドしか作ってなかったので、新しい発見があった。

頑張ればゲーム作れるかもなぁ(作らないけど)。

 

 


RustでGUIアプリ作成

2023-05-31 20:06:14 | Rust

RustのGUIで、テーブルが無い問題。

なかなか解決しないので、ついにwin32apiに手を出してしまった。

NativeWindowsGUIというクレートがあって、win32apiを薄くラップしてるもの。

職場で使うアプリなので、Winだけで動けばいいので問題ない。

 

ちょっと試してみたら、最大化、最小化は問題なく動く(当たり前)。

テーブル(ListView)もある。

 

空き時間で少しづつ作り始めた。

そもそも、これがwin32api初なので、引数が良く分からん。

コードで書けば補完が効くが、deriveマクロで書くと補完が効かないので、ドキュメント見ながら、ちまちま実装。

 

一度pythonで作ってるアプリので、全く同じレイアウトで作る(Rustで作り直す)。

最初Gridレイアウトでいいやと思ってたら、ウィンドウサイズ変えても同期しない。

仕方なく良く分からんダイナミックレイアウトで、ウィンドウサイズ変えると、コントロールサイズが変わるようにする。

取り敢えず動いたけど、ドキュメントに記載がないので、何でこの数値で動いてるのか分からん。

 

コンボボックスx2、テキストインプット、リストビュー、テキストボックスを設置して、それぞれのイベントを実装していく。

イベントの書き方も良く分からんが適当に書いたら動いたからいいか。

最初、全ての処理を書いてたんだけど、これじゃテスト出来ないじゃんって気づいた。

(GUIは、テストコードでテスト出来ない)

 

気づいてしまったので、構造体として外出しして、テスト出来るようにする。

単体テスト通してから、実処理で使用する。

最終的には、GUIいじって動き確認になるけど、なるべくテスト動かせるように実装していく。

 

処理自体はRustなので、今まで頑張って書いてきたRustの流儀で書ける。

まぁ、いつものように所有権問題で、はまるんだけど。

 

毎日ちょっとずつ書くので、あっちで実装した関数を、こっちで使ってるけど、ここでしか使わないので、この引数いらなくね?みたいな箇所がわんさか出てくる。

最後に、全体をチェックして、いらん処理を削っていく。

そんで、なるべくRustっぽいコードにしていく。

 

GUIのコントロールにデータ設定する際に、cloneするしかなくて、各所でcloneしてしまった。

Rc使えばゼロコピー実現出来たかなぁ、と今更ながら思ったり。

すでに、出来上がったので、内部チームに動作確認依頼してる。

これで問題なければ全体周知予定。

 

どうせWinでしか使わないんだから、GUIは、win32apiでいいよね、軽いし。

他のGUIクレートは、どのOSでも動きます!みたいなのばっかりで、動けば問題ないけど、最小化したら落ちるとかクソでしょ。

今後も、GUI必要になったら、win32apiでいいか。

 

今更のようにwin32apiを使ってみたが、Rustでラップしてるので、本来のapi関数を叩いてないため、

未だにwin32apiには無知のまま。

MS嫌いなので、勉強する気もない。

 


Rustの処理時間改善

2023-04-07 21:15:53 | Rust

以前は、結局もとに戻したんだけど、再度挑戦してみた。

 

jwalk使うと自作findと同じになるので、前よりましだ。

処理は何も変えてないけどね。

色々試して、ファイル情報を取得する.metadata()をコメントにすると爆速になる事が判明した。

Windowsのファイル情報取得する処理が遅いの?

それって、標準ライブラリなので、どうにもならなくね?

という事で、クレートを検索したが、高速ファイル情報取得というクレートも存在せず。

 

仕方ないので、metadata()は、放置して、自作findと同じ時間になったので、jwalk版を適用した。

 

そうしたら、次の日以降、ログで処理時間計測すると、爆速になってる???

動作テストはデバッグ版で、本番使用はリリース版使ってる違いはあるけど、マジで?

C#版、23秒。

自作find、62秒。

jwalk版、17秒。

ついにC#版より早くなった。

やった~。処理速度改善した~。

 

結局、何が原因だったのか分からんけど、デバッグ版で速度計測しても意味ねぇという事は分かった。

うーん、テスト実行で速度計測するから、リリース版は使えないし、一度リリース版にして本番適用して、速度計測しないといけないの?

めんどくさっ。

 

まぁ、C#版より早くなったので、とにかく良かった。

やり切った感。