• 締切済み

EDIT 作成時のちらつき防止について

Enterキーを押下された時に画面にEDITBOXを表示し、 再度Enterキーを押下されたらEDITBOXを消す。 という処理を行っているのですが、表示する時も消す時も画面のちらつきが発生します。 このちらつきを防ぐにはどうしたらいいでしょうか? Enterキーが押されたときに、毎回、CreateWindowし、SetWindowLongでWNDPROCを設定しています。 mainWndProc関数の一部 mHwEnter = CreateWindow("EDIT", "ここに入力", WS_CHILD | WS_VISIBLE | WS_BORDER, 173, 380, 12 * 16, 16, mHwMain, NULL, hInst, NULL); mainWndProc = (WNDPROC)GetWindowLong(mHwEnter, GWL_WNDPROC); SetWindowLong(mHwEnter, GWL_WNDPROC, (LONG)WndProcEnter); 再度Enterキーが押されたとき ウインドウを破棄しています。 WndProcEnter関数の一部 SetWindowLong (mHwEnter, GWL_WNDPROC, (LONG)mainWndProc); DestroyWindow (mHwEnter); mHwEnter = NULL; EDITの表示、消去の仕方はWebで調べたのですが、間違っていたらご指摘お願いします。 また、メイン(親)画面は20FPSくらいで描画し続けています。MFCやDirectXは使用していません。 ちらつき防止のわかる方がいたら回答お願いします。

みんなの回答

  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.3

>EDITの表示、消去の仕方はWebで調べたのですが、間違っていたらご指摘お願いします。 普通はコントロールの表示・非表示のためだけに毎回作成・破棄は行いません。遅いですし。 ShowWindow()でSW_SHOW、SW_HIDEを呼ぶだけです。 >InvalidateRect (mHwMain, NULL, FALSE); > >という処理をいれましたがちらつきは改善されません。 これじゃクライアント領域全体を無効化しちゃってますが。考え方が間違ってます。 ちらつく=全体が無効領域にされている なんですから、EDIT破棄後にValidateRectで全体を有効化してEDITがあった矩形のみ無効化しないと。

全文を見る
すると、全ての回答が全文表示されます。
  • muenos
  • ベストアンサー率16% (1/6)
回答No.2

EN_UPDAETなどが無限ルーブして、直後に自動で無限ループが解除させるまでの様子がちらつきだと思います。 WndProcEnterでEN_UPDAETなどの処理をしたらmainWndProcでEN_UPDAETされないようにしないといけないと思います。 別件で、*etWindowLongは*etWindowLongPtrにした方がいいです。

全文を見る
すると、全ての回答が全文表示されます。
回答No.1

何度も画面表示の更新が入る場合にはそのようなちらつきが発生します。 そのような場合には 1) ValidateRect(...)で表示更新領域を削除する。 2) 描画処理。(というかCreateWindowするから自動的にそうなってしまう) 3) ValidateRect()している領域は表示更新されません。 4) そのままではそこには何も表示されない(元のまま)のでCreateWindow(), DestroyWindow() が終わった後に InvalidateRect(...), ShowWindow() してやります。 何か描画アクションが起こるたびに画面を書き直す(Windowsが)からちらつきが発生します。ValidateRect()で「ここの部分は描かなくていいよ」というのをWindowsにまず教えてやります。雑多な処理が終わったときに InvalidateRect() で「やっぱり、ココ描き直して!」とWindowsに指示するわけです。

lilillii
質問者

補足

回答ありがとうございます。 CreateWindow前に recEnter.top = 173; recEnter.left = 380; recEnter.right = 380+12*16; recEnter.bottom = 173+16; ValidateRect(mHwMain, &recEnter); という処理をいれ DestroyWindow後に InvalidateRect (mHwMain, NULL, FALSE); という処理をいれましたがちらつきは改善されません。 これは、EDIT表示時と、消去時のちらつきが解消されるのでしょうか?それともEDITを表示している最中のちらつき防止ほうでしょうか? 説明不足だったかもしれないので、補足しますと、 ちらつきが発生するのは表示した瞬間と、消去した瞬間と、全角文字を入力しEnterキーを押した瞬間の3つの タイミングで、EDIT表示中はちらつきは発生しません。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 次のようにEditを作成し

    hE=CreateWindow ("EDIT",NULL,WS_CHILD|WS_VISIBLE|ES_MULTILINE|ES_AUTOVSCROLL|WS_VSCROLL|WS_BORDER,0,0,0,0,hWmain,HMENU(IDE),hInst,NULL); 使っていますが SetWindowTextでhEの大容量の文字列を送ったのですが 表示させているエディット画面の下に表示画面一行目が最初から何行目にあるか表示させようと思っています どんなメッセージをそれを送れば取得できるでしょうか? 例えばListでいえば i=(int)SendMessage(hL,LB_GETTOPINDEX,0,0); のようなものを知りたいのです

  • VS2008でEDIT今トーロールがつくれない

    VCを学習中です。 書籍の内容をVS2008(VC)で、EDITコントロールを実装使用しますができなくて 困っています。 内容は、 1 VS2008の機能でスケルトンを作成  (メニュー画面とaboutが表示されるものです。MFCとATLは使用していません。) 2 WM_CREATEをWndProcに作成し、CreateWindowを記述 3 実行するとEditコントロールの中にEditコントロールができて、Editコントロールとしては 機能しません。 どなたか、この謎と解決策を教えてください。 ソースの一部分を掲載します。 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; static HWND hwndEdit; switch (message) { case WM_CREATE: hwndEdit = CreateWindow(TEXT("edit"),L"abcdefghijkl", WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL |WS_BORDER|ES_LEFT|ES_MULTILINE |ES_AUTOHSCROLL|ES_AUTOVSCROLL, 100,100,500,500, hWnd, (HMENU)ID_EDIT, ((LPCREATESTRUCT)lParam)->hInstance,NULL); return 0; case WM_SETFOCUS:

  • WNDPROC をクラスのメンバにもちたいです

    ツリーコントロールをクラスにラップしたいのですが、 クラス内のメンバで WNDPROC PrevProc; とすると、 error C2597: 静的でないメンバ 'TreeControlClass::PrevProc' への参照が正しくありません。 というエラーが表示されます。 どうにかできないでしょうか? クラスの外に変数宣言するしかダメでしょうか? よろしくお願いします。 Visual C++.NETで開発 #include<Commctrl.h> class TreeControlClass { private: HWND TreeWnd; WNDPROC PrevProc; public: void WindowCreate(HWND ParentWnd,RECT Rect) { DWORD Style; Style=WS_VISIBLE|WS_CHILD|WS_BORDER|TVS_HASBUTTONS|TVS_HASLINES|TVS_LINESATROOT; int x,y,width,height; x=Rect.left; y=Rect.top; width=Rect.right-Rect.left; height=Rect.bottom-Rect.top; TreeWnd=CreateWindow(WC_TREEVIEW,"",Style,x,y,width,height,ParentWnd,NULL,NULL,NULL); PrevProc=(WNDPROC)GetWindowLong(TreeWnd,GWL_WNDPROC); SetWindowLong(TreeWnd,GWL_WNDPROC,(LONG)TreeProc); return; } void WindowDestroy() { SetWindowLong(TreeWnd,GWL_WNDPROC,(LONG)PrevProc); DestroyWindow(TreeWnd); return; } static LRESULT CALLBACK int TreeProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) { switch(message) { default: return (CallWindowProc(PrevProc, hWnd, message, wParam, lParam)); } } };

  • テキストボックスからフォーカス外す

     editBox = CreateWindow(   "EDIT",   "あああ",   SS_CENTER | WS_CHILD | WS_VISIBLE,   0,0,100,20,   hWnd,   NULL,   hInstance,   NULL); テキストボックスのフォーカスを外すにはどうしたら いいんですか? ESCキーでフォーカスを外そうと思ったら、 テキストボックスにフォーカスがあるせいで case WM_KEYDOWN が動作しません。 フォーカスを外すというソース自体も分かっていません。  case WM_KEYDOWN:   if( wParam == VK_ESCAPE )    ?  break;

  • WindowsAPIの、ウインドウの表示非表示

    WindowsAPIのCreateWindowEx関数で作った 例えば第一引数が WS_EX_TOOLWINDOW|WS_EX_TOPMOST で第四引数が WS_SYSMENU | WS_VSCROLL | WS_SIZEBOX のウインドウを、何かのアクションがあったときいったん非表示にしてから、また何かのアクションがあった時に表示させるには、どのような物を使うのがベストなのでしょうか? プロシージャ内(HWNDはhw)で一例として(…?)試しに以下だけのものでやってみると long lStyle = GetWindowLong(hw, GWL_STYLE); lStyle = ~WS_VISIBLE; SetWindowLong(hw, GWL_STYLE, lStyle); 確かに非表示扱いにはなるようなのですが、これだけではスクリーンは再描画されず、再描画されるには人為的に別ウインドウを移動したりしないといけません。 おそらく「何かによって再描画させられれば」出来ると思うのですが それはどうすれば実現できるのでしょうか? また、これより もっと「こっちの方がいい」といった方法はありますでしょうか?

  • ボタンのスタイル変更

    ボタン1にフォーカスがある時、 BS_DEFPUSHBUTTONのスタイルになり、 Enterキーが使えますよね? ここからTabキーを押下すると、 ボタン1では、フォーカスがないので、 Enterキーはつかえません。 ということは、この時は、BS_DEFPUSHBUTTONのスタイルではない? 自分で、BS_DEFPUSHBUTTONのスタイルのON/OFFを行うには、 どの様にしたら良いでしょうか? SetWindowLong(GetDlgItem(hWnd, GWL_ID), GWL_EXSTYLE, BS_DEFPUSHBUTTON); と書いて、ONの処理は出来た?(太い境界線があるので)のですが、 スタイルOFFとするときの処理がわかりません。 環境は、Win98&SDK&VC6.0で作成してます。

  • Tabでのフォーカス(win32)

    edit = CreateWindow( TEXT("EDIT") , NULL , WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_NUMBER | ES_LEFT , 0 , 0 , 35 , 18 , hWnd , (HMENU)1 , ((LPCREATESTRUCT)(lParam))->hInstance , NULL ); でエディットコントロールを作成しました。 フォーカスがエディットコントロールにある時、TABキーで フォーカスをなくしたいのですが、どうしたらよいでしょうか? デバッガーで追ってみると、WM_KEYDOWNがウィンドウに送られていませんでした。

  • CreateWindowについて

    hE=CreateWindow("EDIT",NULL,WS_CHILD|WS_VISIBLE|ES_MULTILINE|ES_AUTOVSCROLL|WS_VSCROLL|ES_READONLY,0,0,100,100,hW,(HMENU)ID_EDIT,hI,NULL); のようにES_READONLYを入れるとエジットコントロールの背面が灰色になってしまうのですがES_READONLYを入れる前のように背面を白いままにしたいのですが何か方法はありませんか。

  • テキストエディタならばCreateWindow

    を使って hEdit = CreateWindow("EDIT",NULL,WS_CHILD| WS_VISIBLE|ES_WANTRETURN|ES_MULTILINE| ES_AUTOVSCROLL|WS_VSCROLL|ES_AUTOHSCROLL| WS_HSCROLL, 0,0,rc.right,rc.bottom,hWnd,(HMENU)ID_EDIT, hInst,NULL); として char Str[1048576]にテキストをおさめ SetWindowText(hEdit,Str); とすればスクロール関数も使う必要なくカレットもでて文字を簡単に編集できるのですが テキストビューワならば文字を変更する必要が無くカレットもでると困るのでこれが使えません また↓や↑で1行スクロールしないといけません (エディタの場合はカレットが上下端にきたときにスクロールだからちょっと違う) DrawTextだとスクロール関数を使わないといけないような気がするし・・・ 見るだけのテキストビューワを作るのに適した方法やC言語SDK関数を教えてください

  • C言語でのEDITコントロールからの数字の取得について質問があります。

    C言語でのEDITコントロールからの数字の取得について質問があります。 case WM_CREATE: hwndTempo = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("EDIT") , TEXT("120") , WS_CHILD | WS_VISIBLE | ES_LEFT | ES_NUMBER , 0 , 0 , 200 , 30 , hWnd, (HMENU)3, (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE) , NULL); break; このようにEDITコントロールを作成したとき、どのように書かれている数字(初期設定では120)を取得することができるのでしょうか? ためしに文字型で取得してから変換しようと思い、 ボタンを押した時の処理として char szEdit1[128]; GetDlgItemText(hWnd, hwndTempo, szEdit1,64); と入力してみたのですが、 「error C2664: 'GetDlgItemTextW' : 2 番目の引数を 'HWND' から 'int' に変換できません。」 となってしまいました。 最近始めたばかりでインスタンスやウィンドウハンドルの指定などが間違っているのではないかと思いますが、いまひとつよくわかりません。 「GetDlgItemText」の行をコメントアウトすればエディットとボタンコントロールは正常に表示されます。 開発環境がVisual C++ 2008 Express Editionであるため、リソースエディタは使っていません。 サンプルの多くがIDC_EDIT1を使っているのでどう参考にすればよいか良く見えません。 この方法を学習したら「GetDlgItemInt」を使って直接取得してみる予定です。 出来れば単純なサンプルソースを提示していただけると助かります。 ではよろしくお願いします。

このQ&Aのポイント
  • キャンバスに布地を縫い付ける方法について質問があります。具体的には、F60キャンバス(1303mm×970mm)の麻キャンバスにミシンを使って布地を縫い付けることは可能なのか、特に中央付近は手縫いになるのか気になります。
  • また、関連の商品やサービスがあれば教えていただきたいです。通常販売だけでなく、レンタルサービスもあれば嬉しいです。
  • さらに、ミシンの扱い方についても知りたいです。各メーカーごとに特徴があるのか、どのようなことに注意すれば良いのか教えてください。
回答を見る

専門家に質問してみよう