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

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

ProgressCtrlの上に文字を表示

プログレスバーの上に文字を表示する必要が生じたのだが、標準のCProgressCtrlは文字表示機能が無い。どうも、Windowsのデザインガイドではテキストを表示するな!となっているようだ(1次情報未確認)。そこで、他の方が作ったものがないかなーと調べてみるも、バー部分も独自実装とするものしかなかった。そこはWindowsのものを使いたかったんだけどなあ。仕方ないので、reidphoaさんのCInfoProgressBarをベースに、バー表示をWindowsが担当するように改造した。SetWinowTextで表示する文字を設定可能。

Add text on progress control

タブコントロール内のダイアログがESCキーで閉じてしまうのを防ぐ

タブコントロールを実装するには、各タブに相当する枠なしダイアログを用意するのだが、困ったことにESCキーを押すとこのタブ内のダイアログが閉じてしまい、真っ白になってしまう。これを回避するには、タブ内の各ダイアログのOnCancel()をオーバーライドして何もしないようにすればよい。

 

gist551c663846c21afcddbd3044974fc758

CProgressCtrlのSetStateが反映されない

CProgressCtrlの色を変えようとしたがハマったのでメモ。

CProgressCtrlは、WindowsThemeが有効だとプログレスバーの色を変えるSetBarColorが無視される。そこで、SetStateでPBST_NORMAL, PBST_PAUSED, PBST_ERRORのいずれかを指定することでテーマに沿った色に変えることにした。しかし、なぜか変わらない!

ブレークポイントを設定したら変わることに気づいたので、ためしにバーの値更新周期を50msから500msにしてみたら、動いた。こんなの気づかないよ・・・。どこにもドキュメントされてないし。

以下、更新部分のソースコード

 

Updating CProgressCtrl State

追記:どうやら、プログレスバーの長さが変わっている最中にSetStateしても無視されるようだ。Vista以降では、SetPosで長さを変えると、その長さに向かってプログレスバーが伸びるアニメーションをする。このアニメーションをキャンセルすることで、瞬時にSetStateが有効になる。

 以下、サンプルコード。

gist.github.com

ダイアログのコントロール上でも右クリックでメニューを出したい

ダイアログ上で右クリックした際にメニューを表示するには、OnRButtonUpあたりをオーバーライドしてやればいい。しかし、OnRButtonUpはダイアログ上のプログレスバー等の上で右クリックした場合には呼び出されない。これは、ボタンの上で左クリックした場合等を考えると当然の挙動である。

これを解決する方法は2つある。

  1. 各コントロールのクラス(CButton等)を継承したクラスを自作しOnRButtonUpを実装する
  2. 各コントロールのOnRButtonUpを呼び出す処理に割り込む

今回のように、どのコントロールの上で右クリックしてもメニューを出す場合は2.が圧倒的に楽である。では、OnRButtonUpを呼び出す処理に割り込むにはどうすればいいか?MFCではWindowProc()をオーバーライドすればよい。Spy++でメッセージの流れを見たところ、WM_SETCURSORをトリガーに各コントロールのOnRButtonUpを呼び出しているようなので、これに割り込むことにする。

f:id:donadonasan:20180829195728p:plain

以下、サンプルコード。

gist4ebf951cb429e8a6fc482f2dc5f980ea

L4カー モータカーをちまちま更新

モータカーを引き続き更新。

謎の箱更新

写真照合したら寸法狂っていたので修正。また、箱と本体の接続方法を修正。ついでに、ケーブルが出てくるところを正確な形状にした。

f:id:donadonasan:20180828002429p:plain

摺電部

f:id:donadonasan:20180828003811p:plain

L4カー 摺電部

L4カーの摺電部の構造はこうなってるっぽい。すなわち、摺電部はスプリングによりレールに押し付けられていて、接触角の変化は回転軸が吸収する。やってることはシンプルなんだけど、部品点数が多い。これは多分、本体をレール上に置くときのことを考えてのこと。スプリングで摺電部を押し付けるという構造なので、レールが無いときは摺電部がレール位置よりも内側に来る。これでは、車体をレール上に置けない。そこで、おそらく下図のようにパーツを外してから本体を置けるようにしていると思われる。・・・それでも、なぜアームの支点がこんな構造なのかは謎なんだけど。

f:id:donadonasan:20180828004659p:plain

モータカー 集電部 完成

結局モータカーの集電部完成させてしまった。電線むき出しだし、本体に絶縁無しで直接つないでいるように見えるから、正しくはアースなんだろうけど。

これ、バネで集電部を押し付ける構造なんだが、なんでこんなに部品多いんだろう・・・。もしかして、モータカーを設置する際には3連ナットの左右2個および集電部を外して、レールと干渉しないようにするためなのか?

f:id:donadonasan:20180827003552p:plain

モータカー 集電部

f:id:donadonasan:20180827004042p:plain

モータカー 集電部 別角度