|
/*========================================================*/ <<<あゆしゃのC言語プログラミング>>> /*========================================================*/ 第421回 ミニクロック2 発行 2004年2月4日(水曜日) 発行数 約3200 {magclick} /*========================================================*/ はじめに ( 決り文句 ) /*========================================================*/ ・このメールマガジンはまぐまぐさんから発行しています。 ・ジャンルは、マルチメディアのプログラム、C言語です。 ・このメールマガジンは、横60文字で作成しています。 また、インデントはすべて半角スペース4つで構成しています。 ・ここで扱うプログラムは、C言語と半光年以内のものです。 ・登録解除は、まぐまぐさんのホームページでお願いします。 ・まぐまぐさんのバックナンバー(下欄参照)を活用して下さい。 ・ここは私の復習の場です。内容は約1ヶ月内外に私が勉強した 内容になっています。最新の技術があれば、へたれもあります。 ・わかりやすさを優先させる為、たまに嘘があるかもしれません。 ★緊急リンク http://www.kh.rim.or.jp/~tow/nikki-07.htm なんてことはない、日記であり、しかも無許可で直リンク。 ごめんなさい。でもフリーリンクだから。 しかし、そこまでして紹介したい理由があるのです。 内容は、ドラゴンクエストIIの感想。これを見て、私は涙を 流しました。 ・・・絶品です! /*========================================================*/ ご挨拶 /*========================================================*/ こんにちは。あゆしゃです。 駄目といえば、先日、私の家にも光ファイバが来ました! まぁ、それ自体はいいことなのですが、問題は、プロバイダの 契約変更です。 私はプロバイダにぷららを使っています。 ぷららさんは、電話1本で接続設定変更をお願いをしたところ、 「設定を変更いたしますので、2時間ぐらいで有効になります」 といっていただけました。 各サーバか何かにデータをばら撒くのに2時間かかるのかなぁと 勝手に納得し、満足しました。 問題は、もう1つのプロバイダです。 私は2つプロバイダを使っているのですが、もう1つは、 あのニフティなのです。 電話がつながるだけでも4時間かかりましたよ? 平日なのに。 同じように電話で接続設定変更をお願いをしたところ、 「設定を変更いたしますので、1ヶ月ぐらいで有効になります」 ・・・はぁ!? {magclick} /*========================================================*/ 今回のお題 << ミニクロック2 >> /*========================================================*/ ストレスがたまったときには、プログラムですね。 前回のものに修正を加えて、ドラッグできるようにしましょう。 実行ファイル http://ayusya.hp.infoseek.co.jp/Download/MiniClock02Exe.zip VC6.0プロジェクト http://ayusya.hp.infoseek.co.jp/Download/MiniClock02.zip /*========================================================*/ 何が変わったかというと、 ・ヘッダーファイルにメンバ変数追加 CRect m_rcStart; CPoint m_ptStart; BOOL m_bCapture; ・イベントハンドラを3つ追加 afx_msg void OnLButtonDown(UINT nFlags, CPoint point); afx_msg void OnLButtonUp(UINT nFlags, CPoint point); afx_msg void OnMouseMove(UINT nFlags, CPoint point); しました。 そろそろ社会人勉強中の人の季節ですので、少し詳しく説明 します。 /*========================================================*/ やりたいことは、ウィンドウをドラッグできるようにすること です。 普通のウィンドウならば何もしなくてもタイトルバーを ドラッグすれば移動してくれますが、 今回はタイトルバーを取っ払ってしまったので、自分で移動処理 を書く必要が出てきました。 そこで、マウスが押された、マウスが動いた、マウスが放された というイベントを捕まえて、ここで移動処理を表現します。 しかし、マウスがどうした、というイベントは、そのウィンドウ の上にマウスがないと、捕まえられません。 はじめはそれでよいのですが、移動中は、マウスがウィンドウを 飛び出すことは当たり前です。 そこで、マウスキャプチャーというものを使います。 マウスキャプチャーを使うと、それ以降、ウィンドウの上に マウスがない状態であっても、マウスがどうした、というイベント を捕まえることができるようになります。 /*========================================================*/ マウスキャプチャーを開始するのは、マウス左ボタンが押された ぜ!イベントハンドラ関数です。 void CMiniClockDlg::OnLButtonDown(UINT nFlags, CPoint point) この関数の中で、6行プログラムがあります。 1. ::GetCursorPos( &m_ptStart ); // ドラッグ開始位置 ドラッグの開始位置を保存します。 移動中に、この開始座標と現在座標との差分によって、新しい 位置を求めます。 移動するたびに開始位置を更新していると、微妙にずれてくる (気がする)ので、開始座標を決めたら変更しません。 2. SetCapture(); // マウスキャプチャーを開始 CWnd::SetCapture()という関数で、マウスキャプチャーを 宣言します。 この処理を行った後では、マウスがウィンドウの上にいなくて も、マウスのどーのこーのというイベントをもらうことができま す。 3. m_bCapture = TRUE; // キャプチャー中を記録 キャプチャーしていることを記録します。 移動を処理するのはマウスが動いたというイベントハンドラ ですが、キャプチャーしていないときでもこのハンドラは動きます ので、キャプチャー中でっせ、ということを記憶しておきます。 キャプチャーは、開放しないと他のアプリケーションが 困ります。マウスで触れなくなりますから。 なので、必ず開放するためにも、キャプチャー中であることを はっきりと覚えておきます。 4. GetWindowRect( &m_rcStart ); // 現在のウィンドウ座標を取得 先ほどはマウスの座標を記録しましたが、これはウィンドウの 座標です。 このウィンドウ座標も、移動中には変更しません。 この座標に、マウスが移動した差分を足しこんで、新しい座標 を求めます。 5. SetDlgItemText( IDC_STATUS, "移動中です" ); // 移動中である 移動中であるということを、ユーザに明言します。 このような表示は、無意味に思われるかもしれませんが、 ヒューマンインターフェースとして、意外に重要です。 6. CDialog::OnLButtonDown(nFlags, point); 最後に、標準の処理を行います。 さぁこれで、移動の準備ができました。 /*========================================================*/ 実際に移動を行っているのは、マウスが動いた、という イベントハンドラです。 void CMiniClockDlg::OnMouseMove(UINT nFlags, CPoint point) IF文で、キャプチャー中である場合のみに動作するように します。 それから、移動もしていないのに移動を実行するとちらつくので 座標が変化したときだけ処理をするように、 static CPoint last_pos; この変数で前の座標を覚えています。 メンバ変数にしても良かったのですが、クラスのためではなく 関数のための変数なので、スタティックでよいでしょう。 面倒だっただけなのですが、それは秘密。 あとは、ドラッグの開始位置から現在位置を差し引いて差分を 求め、 それをウィンドウの開始位置に足し込んだ座標に、 ウィンドウを移動させます。 ウィンドウの移動には、SetWindowPosを使います。 SetWindowPosで変なことをやっているので、普通にMoveWindowを 使うと、都合が悪いのです。 また、ちょっとマウスが触れただけなのに過剰に反応してピッと 動いてしまうのは、 むかつきますので、 X座標またはY座標のどちらかが8ドット以上動いたときのみに、 新しい座標を計算する処理をしています。 8ドット未満だったときにも、SetWindowPosは必要です。 動いた後、元の位置に来たときに、そこに移動する必要が あるからです。 /*========================================================*/ マウスの左ボタンが上がったら、キャプチャーを終了します。 void CMiniClockDlg::OnLButtonUp(UINT nFlags, CPoint point) これで行っています。 キャプチャーを終了するには、 ReleaseCapture(); // マウスキャプチャーを終了 これで行います。開放とも言います。なのでスペルがリリース なのです。 /*========================================================*/ ついでに、タスクトレイをクリックすると表示されるメニューを 本体をクリックしても出るようにしました。 そのために、 ・メニュー表示を関数として独立 void ShowMenu( LPPOINT ppos ); ・右ボタン押下のイベントハンドラを追加 afx_msg void OnRButtonDown(UINT nFlags, CPoint point); しました。 {magclick} /*========================================================*/ さいごに /*========================================================*/ 私はもう、Excelを全画面表示していなくても、いつもこれを 使っています。 秒が表示されるので、非常に便利です。 秒をベルの時間に合わせておきまして、 お昼のベルと同時にパン屋に走るとか。 <学生かあんたは {magclick} /*========================================================*/ 次回予告 /*========================================================*/ 次回は2月6日(金曜日)に、第422回を送ります。 お題は「空白削除」 続いて、便利ツール第2弾。 お楽しみに! /*========================================================*/ 最後の決り文句 /*========================================================*/ このメールマガジンは、まぐまぐさんから発行しています。 このメールマガジンを解除したい場合は、まぐまぐさんをご利用 ください。このメルマガのまぐまぐアイディーは最後にあります。 このメールマガジンの内容に文面の引用はありませんか? めーらっくすの場合はめーらっくすの利用方に従ってください。 このメールマガジンの内容の、転用、流用、宣伝、リンク、 貧乏性だなぁ なんて大歓迎です。 {magclick} /*========================================================*/ /*========================================================*/ 発行者 あゆしゃ まぐまぐアイディー 0000020674 まぐまぐバックナンバー http://jazz.tegami.com/backnumber/frame.cgi?id=0000020674 あゆしゃの世界 http://ayusya.hp.infoseek.co.jp/ 登録と解除 http://www.mag2.com/m/0000020674.htm ご意見・ご感想・ご質問メール mailto:ayusya@flamenco.plala.or.jp めーらっくす <<過去ログがタイトル別になっています>> http://www.mailux.com/mm_dsp.php?mm_id=MM3E1AEE285AB4F |