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で質問しましょう!
似たような質問が見つかりました
- その他(プログラミング・Web制作) ボールの動きがスムーズに動いてかつ目盛り線描画を維持するためには 4 2023/05/31 10:01
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- Excel(エクセル) 【エクセルマクロ】既に開いているIEの、サイズや表示位置を変更するには 4 2022/12/01 22:57
- その他(プログラミング・Web制作) Pythonにおける物理のシミュレーションでの単位変換について 2 2023/06/02 17:11
- その他(プログラミング・Web制作) Pythonでのかんたんな物理シミュレーションについての書籍 5 2023/06/02 07:37
- JavaScript vertical sliderをautoplayしたい 2 2022/08/25 14:47
- その他(プログラミング・Web制作) Pythonによる物理の斜方投射の位置座標表示について 2 2023/06/05 12:46
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- JavaScript フォームが空欄の時にフォームの外をクリックすると、エラーが出るコードを調べています。 1 2023/06/25 11:51
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
このQ&Aを見た人はこんなQ&Aも見ています
-
性格の違いは生まれた順番で決まる?長男長女・中間子・末っ子・一人っ子の性格の傾向
同じ環境で生まれ育っても、生まれ順で性格は違うものなのだろうか。家庭教育研究家の田宮由美さんに教えてもらった。
-
テキストカーソル位置の取得
C言語・C++・C#
-
Win32のIME制御について
C言語・C++・C#
-
作成したウインドウのサイズを固定するには?
C言語・C++・C#
-
-
4
CStringのFindで文字列検索を行いたいのですが
C言語・C++・C#
-
5
CStringの文字列検索&抜き出しについて
C言語・C++・C#
-
6
EDITコントロールで入力できる文字を制限するには?
C言語・C++・C#
-
7
C言語とWin32APIで全角かなの文字を取得する方法について。
C言語・C++・C#
-
8
imm(日本語入力)が上手く行きません;
C言語・C++・C#
-
9
C言語win32api、エディットボックスから文字列を取得しメッセージ
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エラー Run-Time Check Failur...
-
オーバーレイみたいな処理がしたい
-
【Windowsアプリ】ファイルのド...
-
ツリーコントロールの開閉アイ...
-
C言語win32api、エディットボッ...
-
WM_CREATE について
-
信頼区間の1.96や1.65ってどこ...
-
Enterキーを押されたら次の処理...
-
「Aに対するBの割合」と「Aに対...
-
C言語 プログラム
-
プログラムの実行時に'<'でリダ...
-
DWORDの実際の型は何でしょうか
-
C++にてtemplateで受け取った任...
-
プログラムでの数字につく”f”の...
-
数学 確率変数Xは、X=2またはX...
-
「指定されたキャストは有効で...
-
構文エラー";"が型の前にあり...
-
2÷3などの余りについて
-
fgetsなどのときのstdinのバッ...
-
変数とパラメータとは違うもの...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
音量調節
-
return文がない場合の戻り値は...
-
C#のswitch文を簡略化したいの...
-
ゲームとかの解像度変更&全画...
-
エラー Run-Time Check Failur...
-
コンソールアプリケーションの...
-
キャレットの現在位置の表示 (W...
-
エディットボックスの背景の色...
-
COMPORTマルチスレッドで例外発生
-
ツリーコントロールの開閉アイ...
-
C言語win32api、エディットボッ...
-
Win32APIにて、ウィンドウ全体...
-
Win32APIでウィンドウを中央に...
-
エディットコントロール入力時...
-
ダイアログプログラムでEnterキ...
-
不思議な現象が起こるプログラ...
-
Win32のファイルダイアログのサ...
-
C言語のswitch case文で、scanf...
-
WM_CREATE について
-
ボタンのアイコン表示
おすすめ情報