ドナドナされるプログラマのメモ

Windows用アプリのプログラミングメモ

ダイアログバー上のエディットボックスから文字列を取得する方法

ダイアログバー上のエディットボックスから文字列を取得するのにちょっと苦労したのでメモ。

問題の背景

ダイアログを作る場合、通常はCDialog等を継承した、そのダイアログ固有のクラスを作成する。しかしMicrosoft曰く、CDialogBarは通常固有のクラスを作成しないらしい。これは、ダイアログバーはメインウィンドウの一部で、各コントロールからのメッセージはメインウィンドウのウィンドウプロシージャで処理するという設計だからだろう。このため、メッセージハンドラはCMainFrameに書く必要がある。*1

問題

しかし、固有のクラスを作らなかった場合、メッセージハンドラにてダイアログバー上のエディットボックスにはどうやってアクセスすればよいのだろうか?単純にCMainFrameからGetDlgItemText(ID_DlgBar_Edit)を呼び出しても失敗するし、固有のクラスを作っても上手く行かない。

解決方法

実は答えは単純で、CMainFrame上のメッセージハンドラから、ダイアログバーのオブジェクト(デフォルトだとm_wndDlgBarだと思う)に対しGetDlgItemText(ID_DlgBar_Edit)すればよい。

m_wndDlgBar.GetDlgItemText(ID_DlgBar_Edit, str);

その他の操作をしたい場合は、同様にGetDlgItem()すればよい。

*1:なお、リソースエディタはこの仕様に非対応なため、メッセージハンドラは手動で追加する必要があるようだ。

mozjpegをつかった画像変換ソフトの開発 その8

mozjpegを多並列で実行するGUIを備えた画像変換ソフト、無事Vectorにて公開。

www.vector.co.jp

 そのうち、英語版もどこかで公開予定だけど、どこにしよう?Vectorってどう見ても国内オンリーなのよね。英語ページを作れる気がしない。

2020/04/24追記

githubにて英語版を公開しました。
Released MozJpegGUI which is multi-threaded GUI interface for mozjpeg.

github.com

CDocumentからCViewを取得する一例

今時ドキュメントビューアーキテクチャなんて人は居ないだろうけど、メモ。

CDocumentからCViewにメッセージを投げたいときや関数を直接呼び出したいときに困るのが、CViewのアドレス取得方法。特に、自分はCSplitterWndを多用したためCViewが複数あり決め打ち取得ができなずに困ってしまった。そこで以下のような簡単なコードを書いてみた。

Example of finding CView from CDocument

ここにたどり着くまでに4時間かかってしまったorz

CArchive::ReadString, CArchive::WriteStringの罠

CArchive::ReadString()とCArchive::WriteString()を使って文字列を読み書きしようとしたら文字化けしてハマったのでメモ。

以下のようなコードを書いたら、読み込み時に文字化けした。

 

void Serialize(CArchive &ar){

 TCHAR path[MAX_PATH+1];

 if(ar.IsStoring()){  // save

  (中略)

  ar.WriteString(path);

} else {  // load

  ar. ReadString(path, MAX_PATH);

}

 原因はCArchive::WriteString()とCArchive::ReadString()の設計が非対称なため。ReadString()が'\0'までを読み込む関数だと思ったら大間違いで、こいつは'\n'までを読み込む関数。一方、WriteString()は’\0'の直前までを書き出す関数で、書き終わっても'\n'を付与しない。つまり、読み込みと書き込みで区切り文字が異なるのだ。そのため上記プログラムだとMAX_PATHまで読んでしまい、本来読むべき領域からオーバーランし文字化けしたデータとなる。

また、この仕様だと'\n'を含む文字列をWriteStringした場合、ReadStringの処理がかなり困ったことになりそうである。すなわち、改行がある場合は意図したよりも短い文字列が読み込まれてしまう。

なんというか、getstr()との互換性をもたせようとした?せいで最悪な事態になっている気がする。この仕様を審査承認した人たちの罪は大きいと思う。

リソースエディタがWS_EX_COMPOSITEDを認識しない

とあるリソースをVisual Studio2019で開こうとしたら、error RC2104: undefined keyword or key name: WS_EX_COMPOSITED というエラーが出た。

f:id:donadonasan:20200305004914p:plain

error RC2104: undefined keyword or key name: WS_EX_COMPOSITED

でも、おかしい。このキーワードはWindowsに存在しているものなのだ。色々と調べてみたところ、Visual Studio2017からあるバグのようだ。WS_EX_COMPOSITEDを設定したダイアログはWindows8で正常に動作しないことと関係あるのかもしれない。

解決方法はとても簡単で、resource.hの先頭に以下を追加すればよい。

#define WS_EX_COMPOSITED 0x02000000L

 

mozjpegをつかった画像変換ソフトの開発 その7

mozjpegを使った画像変換ソフト、開発が一段落した。

以下に121個のpngファイルを処理した場合の例を示す。64bit版では約6秒で全ファイルの処理が終わった。


MozJpegGUI 64bit ver. example

なお、32bit版と64bit版を作ったが処理速度は以下のように64bit版のほうが8%ほど早いようだ。メモリ制約も64bit版のほうが少なく、特に理由がない限り64bit版を使うべきだろう。

計433MBのpngファイル911個を処理するのにかかった時間

x86: 115.9 sec.
x64: 106.7 sec.