Win32APIの習作としてエディタを作っているのですが,
ステータスバーに現在のキャレット位置を表示する部分で困っています.
いろいろ調べて下記のコードを書いてみたのですが,
エディットコントロールに更新が無いとき(矢印キーで移動など)
にキャレット位置の更新ができないです.
良い方法がありましたらご教授下さい.
(ここのサンプルコードが良いとかでもありましたらお願いします.)
////////////////////////////////////////////////////////////////
// MyEditor.c
static const int FONT_WIDTH = 6;
static const int FONT_HEIGHT = 18;
int __stdcall WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow)
{
...略...
}
LRESULT __stdcall WndProc(HWND hWnd, UINT uMsg, WPARAM wp, LPARAM lp)
{
...略...
switch (uMsg) {
...略...
case IDC_EDIT:{
char str[64];
POINT pt = {0, 0};
RECT rc = {0, 0, 0, 0};
GetCaretPos(&pt);
wsprintf(str, "現在のキャレット位置 (%d, %d)",
pt.x / FONT_WIDTH, pt.y / FONT_HEIGHT);
SendMessage(hStatusbar, SB_SETTEXT, 1, (LPARAM)str);
GetClientRect(hStatusbar,&rc);
InvalidateRect(hStatusbar, &rc, TRUE);
break ;}
...略...
}
return 0L;
}
No.1ベストアンサー
- 回答日時:
★アドバイス
・エディット・ボックスをサブクラス化してWM_KEYDOWNで
カーソルキーの移動を監視。移動されていればキャレット位置の
表示をすれば良いでしょう。
http://wisdom.sakura.ne.jp/system/winapi/win32/w …→『サブクラス化』
http://wisdom.sakura.ne.jp/system/winapi/win32/w …→『キーボードイベント』
アドバイスありがとうございます.
リンクを参考に下記のように変更し,
ひとまず目的を達成できました.
しかし, hStatusbar が,
EditProc() 内で取得する方法がわからなかったため,
グローバルになってしまいました.
FindWindow() という関数で hStatusbar を取得しようと
思ったのですが,CreateStatusWindow() を使用しているので
クラス名とウィンドウ名がわかりません.
できればこれも解決法をお願いします.
ハンドルを得る方法は他の場面でも重要になると思いますので.
// MyEditor.c
static HWND hStatusbar;
int __stdcall WinMain(...){}
LRESULT __stdcall EditProc(HWND hEdit, UINT uMsg, WPARAM wp, LPARAM lp)
{
switch (uMsg) {
case WM_KEYDOWN:
case WM_LBUTTONDOWN:{
char str[64] = {0};
POINT pt = {0, 0};
RECT rc = {0, 0, 0, 0};
GetCaretPos(&pt);
wsprintf(str, "現在のキャレット位置 (%d, %d)",pt.y / FONT_HEIGHT, pt.x / FONT_WIDTH);
SendMessage(hStatusbar, SB_SETTEXT, 1, (LPARAM)str);
GetClientRect(hStatusbar, &rc);
InvalidateRect(hStatusbar, &rc, TRUE);
break;}
}
return CallWindowProc(DefEditProc, hEdit, uMsg, wp, lp);
}
LRESULT __stdcall WndProc(...)
{
...略...
switch (uMsg) {
case WM_CREATE:
GetClientRect(hWnd, &rc);
hEdit = CreateMultilineEditWindow(hWnd, rc);
// エディットウィンドウのサブクラス化
DefEditProc = (WNDPROC)GetWindowLong(hEdit, GWL_WNDPROC);
SetWindowLong(hEdit, GWL_WNDPROC ,(LONG)EditProc);
// コモンコントロール関係の初期化
InitCommonControls();
// ステータスバーを作成
hStatusbar = CreateStatusWindow(WS_CHILD | WS_VISIBLE | CCS_BOTTOM | SBARS_SIZEGRIP,
"ステータスバー", hWnd, IDC_STATUS);
SendMessage(hStatusbar, SB_SETPARTS, MY_SB_PART_COUNT, (LPARAM)rightEdgePosition);
break;
...略...
}
return 0L;
}
No.2
- 回答日時:
★アドバイス
>ハンドルを得る方法は他の場面でも重要になると思いますので.
↑
ハンドルを取得する方法よりもサブクラス化したEditProcから
親プロシージャにキャレット位置の変更を通知すれば楽です。
・仕組みは
(1)EditProcでSendMessageを使いWM_APP+1などを送る
(2)親プロシージャでWM_APP+1を受け取る
(3)受け取ったときにステータスバーに位置を表示
サンプル:
#define WM_MY_STATUSBAR(WM_APP + 1)
LRESULT __stdcall WndProc(...)
{
static HWND hStatusbar; ←ここに書く(ここでも良いかな?)
switch ( uMsg){
case WM_CREATE:
...略...
// ステータスバーを作成
hStatusbar = CreateStatusWindow( …略… );
break;
case WM_MY_STATUSBAR:
{
char str[64];
POINT pt;
RECT rc;
GetCaretPos( &pt );
wsprintf(str, "現在のキャレット位置 (%d, %d)",pt.y / FONT_HEIGHT, pt.x / FONT_WIDTH);
SendMessage( hStatusbar, SB_SETTEXT, 1, (LPARAM)str );
GetClientRect( hStatusbar, &rc );
InvalidateRect( hStatusbar, &rc, TRUE );
break;
}
}
return 0L;
}
LRESULT __stdcall EditProc(HWND hEdit, UINT uMsg, WPARAM wp, LPARAM lp)
{
switch ( uMsg ){
case WM_KEYDOWN:
case WM_LBUTTONDOWN:
SendMessage( GetParent(hEdit), WM_MY_STATUSBAR, 0, 0 );
break;
}
return CallWindowProc( DefEditProc, hEdit, uMsg, wp, lp );
}
こんな感じでどうでしょうか。
※インデントは全角空白を使っています。
この回答への補足
WM_MY_STATUSBAR を受け取った後のキャレット位置の表示処理ですが,
フォント幅は文字に依存するため,定数 FONT_WIDTH で キャレットの
クライアント座標 pt.x を割って求めるとずれてしまう問題が起きました.
そこで,EM_CHARFROMPOS を使用して以下のように変更してみたのですが,
y 方向のスクロールバーが動き出すあたりから pt.x の値が意図しない
ものになってしまいます.2Byte ずつ増えているので,どこかで \r\n
を拾っているのかもしれないです.
できればアドバイスを頂けないでしょうか?
case WM_MY_STATUSBAR:{
char str[64];
POINT pt = {0, 0};
RECT rc;
DWORD chPos;
GetCaretPos(&pt);
chPos = SendMessage(hEdit, EM_CHARFROMPOS, 0, MAKELPARAM(pt.x, pt.y));
pt.y = HIWORD(chPos);
chPos = SendMessage(hEdit, EM_CHARFROMPOS, 0, MAKELPARAM(pt.x, 0));
pt.x = LOWORD(chPos);
wsprintf(str, "現在のキャレット位置 (%d, %d)", pt.y, pt.x);
SendMessage(hStatusbar, SB_SETTEXT, 1, (LPARAM)str);
GetClientRect(hStatusbar,&rc);
InvalidateRect(hStatusbar, &rc, TRUE);
break;}
※インデントに全角スペースを使いました.
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
高校生はアルバイトするべきだろうか?賛成だったら「賛」、否定だったら「否」を文頭においてあなたの意見を教えてください。
-
フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
あなたが普段思っている「これまだ誰も言ってなかったけど共感されるだろうな」というあるあるを教えてください
-
映画のエンドロール観る派?観ない派?
映画が終わった後、すぐに席を立って帰る方もちらほら見かけます。皆さんはエンドロールの最後まで観ていきますか?
-
海外旅行から帰ってきたら、まず何を食べる?
帰国して1番食べたくなるもの、食べたくなるだろうなと思うもの、皆さんはありますか?
-
天使と悪魔選手権
悪魔がこんなささやきをしていたら、天使のあなたはなんと言って止めますか?
-
テキストカーソル位置の取得
C言語・C++・C#
-
WS_TABSTOPが機能するコントロールを作る
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
音量調節
-
C言語win32api、エディットボッ...
-
コンソールアプリケーションの...
-
猫でもわかるWindowsプログラミ...
-
エラー Run-Time Check Failur...
-
c言語の配列を使ってサイコロを...
-
2÷3などの余りについて
-
プログラムでの数字につく”f”の...
-
「指定されたキャストは有効で...
-
DWORDの実際の型は何でしょうか
-
プログラミング初心者です。 Py...
-
「Aに対するBの割合」と「Aに対...
-
Aの値からBの値を除するとは??
-
#define _CRT_SECURE_NO_WARNIN...
-
複数桁10進数の*桁目だけを抽出...
-
C++のfor文について
-
C言語を実行すると-infが出てき...
-
信頼区間の1.96や1.65ってどこ...
-
正負を反転させて出力するプロ...
-
マイナスからプラスへ転じた時...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
音量調節
-
C言語win32api、エディットボッ...
-
エラー Run-Time Check Failur...
-
ウィンドウハンドルがメッセー...
-
ダイアログプログラムでEnterキ...
-
Win32APIでウィンドウを中央に...
-
エディットコントロール入力時...
-
MessageBoxについて
-
ボタンのアイコン表示
-
LoadImageを使用し、タイトルバ...
-
オーバーレイみたいな処理がしたい
-
仮想リストの指定行の色(バー...
-
コンソールアプリケーションの...
-
COMPORTマルチスレッドで例外発生
-
C#のswitch文を簡略化したいの...
-
エディットボックスの背景の色...
-
Win32のファイルダイアログのサ...
-
WM_CREATE について
-
ウィンドウのサイズ変更について
-
WinAPIでの画像高速切り替え表...
おすすめ情報