マンガでよめる痔のこと・薬のこと

Win32APIでタイマーを作成しましたが
時間は正しく表示されましたが画面がチカチカしてしまいます
これを防止するにはどうすればよろしいのでしょうか?

よろしくお願いします

このQ&Aに関連する最新のQ&A

A 回答 (3件)

#include <windows.h>



/* このファイルで使用する定数 */
#define CASE   break;case
#define DEFAULT break;default
#
#define MAX_WIDTH (500) // 画面の横サイズ
#define MAX_HEIGHT (300) // 画面の縦サイズ
#define TID_CLOCK (9868) // タイマーID
#define TID_CYCLE (10)  // タイマー間隔

//ウィンドウプロシージャ
LRESULT CALLBACK WndProc( HWND hWnd, UINT msg, WPARAM wp, LPARAM lp )
{
 static HFONT hFont; // フォント
 static HDC  hMemDC; // メモリデバイスコンテキスト
 static HBITMAP hMemBMP; // ビットマップ
 
 switch ( msg ){
  CASE WM_CREATE:
  {
   HDC hDC;
   
   if ( (hDC = GetDC(hWnd)) != NULL ){
    // メモリデバイスコンテキストを作成
    hMemDC = CreateCompatibleDC( hDC );
    hMemBMP = CreateCompatibleBitmap( hDC, MAX_WIDTH, MAX_HEIGHT );
    SelectObject( hMemDC, hMemBMP );
    
    // メモリデバイスコンテキストの背景を真っ白に描画
    SelectObject( hMemDC, GetStockObject(NULL_PEN) );
    SelectObject( hMemDC, CreateSolidBrush(RGB(0xFF,0xFF,0xFF)) );
    Rectangle( hMemDC, 0, 0, MAX_WIDTH, MAX_HEIGHT );
    DeleteObject( SelectObject(hMemDC,GetStockObject(WHITE_BRUSH)) );
    
    // 解放
    ReleaseDC( hWnd, hDC );
   }
   hFont = create( 23, SHIFTJIS_CHARSET, TEXT("HGS明朝E") );
   SetTimer( hWnd, TID_CLOCK, TID_CYCLE, NULL );
  }
  CASE WM_CLOSE:
  {
   LPCTSTR lpTitle = TEXT("確認");
   LPCTSTR lpText = TEXT("終了してもよろしいですか");
   UINT uStyle = (MB_YESNO | MB_ICONQUESTION);
   
   if ( MessageBox(hWnd,lpText,lpTitle,uStyle) == IDYES ){
    if ( !KillTimer(hWnd,TID_CLOCK) ){
     MessageBox( hWnd, TEXT("KillTimerエラー"), TEXT("エラー"), MB_OK | MB_ICONQUESTION );
    }
    DestroyWindow( hWnd );
   }
  }
  CASE WM_DESTROY:
   DeleteObject( hFont );
   DeleteObject( hMemBMP );
   DeleteDC( hMemDC );
   PostQuitMessage( 0 );
  CASE WM_TIMER:
  {
   static LPCTSTR lpString1 = TEXT("プログラム開始時刻/または更新時刻は");
   static LPCTSTR lpString2 = TEXT("でした左クリックで更新");
   TCHAR szBuff[ 256 ];
   SYSTEMTIME st;
   
   // 時間取得と文字列作成
   GetLocalTime( &st );
   wsprintf( szBuff, TEXT("%02d:%02d:%02d.%03d"),
    st.wHour, st.wMinute, st.wSecond, st.wMilliseconds );
   
   // メモリデバイスコンテキストに描画
   SelectObject( hMemDC, hFont );
   TextOut( hMemDC, 100, 10, lpString1, lstrlen(lpString1) );
   
   SetTextColor( hMemDC, RGB(0,23,200) );
   TextOut( hMemDC, 150, 70, szBuff, lstrlen(szBuff) );
   
   SetTextColor( hMemDC, RGB(0,0,0) );
   TextOut( hMemDC, 185, 130, lpString2, lstrlen(lpString2) );
   
   // 再描画の指示(更新リージョンの追加)
   InvalidateRect( hWnd, NULL, FALSE );
  }
  CASE WM_PAINT:
  {
   PAINTSTRUCT ps;
   HDC hDC;
   
   // メモリ・デバイスコンテキストを画面のデバイスコンテキストに転送
   hDC = BeginPaint( hWnd, &ps );
   BitBlt( hDC, 0, 0, MAX_WIDTH, MAX_HEIGHT, hMemDC, 0, 0, SRCCOPY );
   EndPaint( hWnd, &ps );
  }
  CASE WM_LBUTTONDOWN:
   SendMessage( hWnd, WM_CLOSE, 0, 0 );
  DEFAULT:return DefWindowProc( hWnd, msg, wp, lp );
 }
 return 0;
}
    • good
    • 0
この回答へのお礼

説明、アドバイスありがとうございました。
ゲームのちらつき防止でパッときました(DxLibで体験しました)
ウィンドウプロージャのソース丸ごとつけてもらって助かりました。

お礼日時:2007/06/05 03:14

★アドバイス


・タイマー間隔が 10ms ですね。
 これって 1 秒間に最大 100 回の描画が行われることになります。
 普通にデバイスコンテキストに描画してしまうと間違いなく『ちらつき』ます。
・解決策はメモリ・デバイスコンテキストを用意してそこに描画します。
 そして WM_PAINT でメモリ・デバイスコンテキストの内容を画面のデバイスコンテキストに
 BitBlt() 関数などで転送します。この方法ならば『ちらつき』が発生しません。
 なお、このような方法はダブルバッファなどと呼ばれているものです。
 ゲームではお馴染みです。『ちらつき』を発生させない基本です。
・サンプルを次の回答で載せておきます。どうぞ。

その他:
・KillTimer() 関数は BOOL 型なので論理反転を使って判定した方が良いと思います。0 で比較するよりは。
 InvalidateRect() 関数の第3引数は FALSE にします。TRUE にすると『ちらつき』ます。
 メモリ・デバイスコンテキストをそのまま画面のデバイスコンテキストに転送しているので
 FALSE にしてかまいません。
・あと WM_TIMER の部分で今まで WM_PAINT で記述していた描画処理を記述します。
 今までは hDC に描画していましたが、メモリ・デバイスコンテキスト(hMemDC)に描画します。
 描画の方法は同じです。hDC→hMemDC にするだけです。
・あと strlen() ではなく lstrlen() 関数を使って下さい。strlen() は C関数のランタイムです。
 Win32 API では lstrlen、lstrcmp、lstrcpy、lstrcat などの関数群が用意されています。
・以上。参考に!
    • good
    • 0

★アドバイス


・スタティック・コントロールを文字列を1秒間に数回表示させるとチラツキます。
 でも、よく分かりませんのでソースを貼り付けて下さい。
・その後にアドバイスします。→プロシージャ関数の重要な部分のみでよい。

この回答への補足

//ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
static HFONT hFont;
static char jikan[64];
HDC hdc;
PAINTSTRUCT ps;
SYSTEMTIME st;
int id;


switch (msg)
{
case WM_CREATE:
SetTimer(hWnd , 9868 , 10 ,NULL);
hFont=create(23,SHIFTJIS_CHARSET,"HGS明朝E");
break;
case WM_TIMER:
GetLocalTime(&st);
wsprintf(jikan,"%d時%d分%d秒%d",st.wHour,st.wMinute,st.wSecond,st.wMilliseconds);
InvalidateRect(hWnd , NULL , true);
break;
case WM_LBUTTONDOWN:
SendMessage(hWnd , WM_CLOSE , 0 , 0);
break;
case WM_PAINT:
hdc=BeginPaint(hWnd , &ps);
SelectObject(hdc , hFont);
TextOut(hdc ,100 , 10 , "プログラム開始時刻/または更新時刻は" , 36);
SetTextColor(hdc , RGB(0, 23, 200) );
TextOut(hdc ,150 , 70 , jikan , (int)strlen(jikan));
SetTextColor(hdc , RGB(0, 0 , 0) );
TextOut(hdc ,185 , 130 , "でした左クリックで更新" , 22);
EndPaint(hWnd , &ps);
break;
case WM_CLOSE:
id = MessageBox(hWnd,
TEXT("終了してもよろしいですか"),TEXT("確認"),
MB_YESNO | MB_ICONQUESTION);
if (id == IDYES)
{
if(KillTimer(hWnd , 9868)==0){
MessageBox(hWnd , "KillTimerエラー" , "エラー", MB_OK | MB_ICONQUESTION);
}
DestroyWindow(hWnd);
}
break;
case WM_DESTROY:
DeleteObject(hFont);
PostQuitMessage(0);
break;
default:
return (DefWindowProc(hWnd, msg, wp, lp));
}
return 0;
}

ソースはりつけました。お願いします

補足日時:2007/06/04 01:23
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QInvalidateRectの使い方について

InvalidateRectの使い方ですが、ヘルプを見たところ、下記のように表記されていました。
BOOL InvalidateRect(

HWND hWnd, // handle of window with changed update region

CONST RECT *lpRect,

// address of rectangle coordinates

BOOL bErase // erase-background flag

);
しかし、実際、使ってみると
InvalidateRect(&rct,FALSE);とするだけで、コンパイルは通ります。
※&rctはlpRectのように再描画する領域を指定しています。

私の希望としては、指定した部分だけ再描画をかけ、指定外の部分は、再描画されず、画像がのこり、最終的には一つの絵となって欲しいのですが。
これは引数が2つだから起きているアクシデントなのでしょうか。
InvalidateRctの使い方を教えていただければと思います。よろしくお願いします。

InvalidateRectの使い方ですが、ヘルプを見たところ、下記のように表記されていました。
BOOL InvalidateRect(

HWND hWnd, // handle of window with changed update region

CONST RECT *lpRect,

// address of rectangle coordinates

BOOL bErase // erase-background flag

);
しかし、実際、使ってみると
InvalidateRect(&rct,FALSE);とするだけで、コンパイルは通ります。
※&rctはlpRectのように再描画する領域を指定しています。

私の希望としては、指定した部分だ...続きを読む

Aベストアンサー

 こんにちは。

>>InvalidateRect(&rct,FALSE);とするだけで、コンパイルは通ります。
 コンパイル出来たのは、MFCのCWndクラスのメンバ関数の方を書いたからではないでしょうか。
 ::InvalidateRect(HWND, const RECT*, BOOL)を内部で呼び出しているのです。
 
 ↓質問者様が書いたのは此れの事では?
 void CWnd::InvalidateRect(const RECT* lpRect, BOOL bErase)
 {
::InvalidateRect(m_hWnd, lpRect, bErase);
 }

 「CWnd::InvalidateRect(MFC)」
 http://msdn.microsoft.com/ja-jp/library/2f3csed3(VS.80).aspx

>>私の希望としては、指定した部分だけ再描画をかけ、指定外の部分は、再描画されず、画像がのこり、最終的には一つの絵となって欲しいのですが。
 要するには、特定の領域を指定し、その部分に何かを表示したいと言うことでしょうか?
 で、あるのでしたら BitBlt()/StretchBlt() 辺りで描写した方が手っ取り早いかもしれません。

 「CDCのメンバ」
 http://msdn.microsoft.com/ja-jp/library/4acfw2ha.aspx

>>InvalidateRctの使い方
 無理矢理再描写をさせる時位にしか使用した事が無いので、これ以上は筆舌に尽くしがたいです。

 以下が参考になるかもしれません。
 http://wisdom.sakura.ne.jp/system/winapi/win32/win35.html

 後はMFCと言う物がどの様に構成されているかも理解しておくと、より良いと思います。

 「MFCの階層図」
 http://msdn.microsoft.com/ja-jp/library/ws8s10w4(VS.80).aspx

 こんにちは。

>>InvalidateRect(&rct,FALSE);とするだけで、コンパイルは通ります。
 コンパイル出来たのは、MFCのCWndクラスのメンバ関数の方を書いたからではないでしょうか。
 ::InvalidateRect(HWND, const RECT*, BOOL)を内部で呼び出しているのです。
 
 ↓質問者様が書いたのは此れの事では?
 void CWnd::InvalidateRect(const RECT* lpRect, BOOL bErase)
 {
::InvalidateRect(m_hWnd, lpRect, bErase);
 }

 「CWnd::InvalidateRect(MFC)」
 http://msdn.microsoft.com/ja-jp/l...続きを読む

Qダイアログ内コントロールの位置取得について

いつもお世話になっております。

ダイアログ内に配置されているコントロールの位置の取得方法について
ご教授頂きたく質問させていただきました。

私が試したところGetWindowRect( コントロールハンドル, &rc );
とするとありえないぐらい大きな座標が帰ってきます。

上記の方法ではうまくいきません。
ご教授よろしくお願いいたします。

Aベストアンサー

>http://msdn.microsoft.com/ja-jp/library/cc364604.aspx
より
>クライアント座標はクライアント領域の左上端からの相対座標なので、左上端の座標は常に (0,0) となります。
となっているため
>GetClientRectでダイアログ内の相対位置を取れます。
は間違っていました。

>もしかしたら便利な関数が存在するのでしょうか?
ないのかなぁと。
かわりにこんな関数を作っておくとか。

BOOL GetDlgItemRect(HWND hDlg, int nIDDlgItem, RECT* rct)
{
  BOOL bRet = FALSE;
  HWND hWnd = GetDlgItem(hDlg, nIDDlgItem);
  if (hWnd != NULL)
  {
    bRet = GetWindowRect(hWnd, rct);
    {
      bRet = ScreenToClient(hDlg, rct);
    }
  }
  return bRet;
}

>http://msdn.microsoft.com/ja-jp/library/cc364604.aspx
より
>クライアント座標はクライアント領域の左上端からの相対座標なので、左上端の座標は常に (0,0) となります。
となっているため
>GetClientRectでダイアログ内の相対位置を取れます。
は間違っていました。

>もしかしたら便利な関数が存在するのでしょうか?
ないのかなぁと。
かわりにこんな関数を作っておくとか。

BOOL GetDlgItemRect(HWND hDlg, int nIDDlgItem, RECT* rct)
{
  BOOL bRet = FALSE;
  HWND hWnd = GetDlgIt...続きを読む

QCStringからchar*への型変換について教えてください。

以前の質問に

int型 → CString型/char型

がありましたが、

CString型をchar*型に変換する方法を
教えていただければありがたいです。

MSDNで「LPCTSTRキャスト」が説明されていましたが、
例が載ってないのでよくわかりませんでした。

よろしくお願いします。

Aベストアンサー

目的にもよりますが一時的にchar配列として使いたいならCString::GetBuffer()が利用できます。
char配列としての利用が終わったらCString::ReleaseBuffer()する必要がありますが。

直接CString内の文字列を扱う必要があるならCString::operator LPCTSTRで文字列ポインタが得られます。
ただし、CStringオブジェクトをいじると無効ポインタなる可能性があるので気をつけてください。

MSDNのMicrosoft Foundation Classリファレンス→CString→クラスメンバで確認してください。

Qダイアログボックスで指定したサイズどおり表示されない

ダイアログボックスで指定したサイズがメイン上では約2倍の大きさになって表示されてしまい、困っています。

メニューリソースは以下のとおりです。
MYDLG DIALOG DISCARDABLE 25, 50, 100, 150
STYLE WS_VISIBLE | WS_CHILD | DS_CONTROL
CAPTION "Dialog"
FONT 9, "MS Pゴシック"
BEGIN
END

WndProc内にダイアログを貼り付けています。
if(hDlgWnd) break;
hDlgWnd = CreateDialog((HINSTANCE)GetWindowLong(hWnd,GWL_HINSTANCE),"MYDLG",hWnd,DialogProc);

それが実際にウィンドウを開くとダイアログがだいたいですが(50,115,200,340)のように表示されてしまいます。

VC++ Ver.6.0です。コンパイラ等の問題でしょうか。
ご存知の方、宜しくお願いします。

Aベストアンサー

★コンパイラ等の問題ではありません。
・もともとダイアログのサイズはピクセル数での指定ではないのです。
 この基本を知らないと今回の質問が出てくるようですね。
 ダイアログは『ダイアログ・ベース単位』でサイズが決まります。
 これはダイアログに設定されているフォントの高さなどから変化するのです。
 次のリンクを読んで下さい。
 http://wisdom.sakura.ne.jp/system/winapi/win32/win84.html→『ダイアログ』
 かなり最初の方に
>ただし、ダイアログで指定する座標、サイズはピクセルではないので注意してください
>ダイアログの場合、座標系は文字サイズを基準としているのです
 という事が書かれています。

解決策:
・CreateDialog() でダイアログを作成したときにダイアログの WM_INITDIALOG で
 ウインドウのサイズをピクセル値で設定しなおす処理を行います。
 つまりは
 case WM_INITDIALOG:
  SetWindowPos( hDlg, NULL, 25, 50, 100, 150, (SWP_NOZORDER|SWP_NOOWNERZORDER) );
  return TRUE;
 という記述を追加します。
 重要なのは SetWindowPos() 関数でウインドウの位置とサイズをピクセル値で
 設定することです。
・以上。『ダイアログ・ベース単位』と『ピクセル値』は違います。注意。

参考URL:http://wisdom.sakura.ne.jp/system/winapi/win32/win84.html

★コンパイラ等の問題ではありません。
・もともとダイアログのサイズはピクセル数での指定ではないのです。
 この基本を知らないと今回の質問が出てくるようですね。
 ダイアログは『ダイアログ・ベース単位』でサイズが決まります。
 これはダイアログに設定されているフォントの高さなどから変化するのです。
 次のリンクを読んで下さい。
 http://wisdom.sakura.ne.jp/system/winapi/win32/win84.html→『ダイアログ』
 かなり最初の方に
>ただし、ダイアログで指定する座標、サイズはピクセルで...続きを読む

Qwin32api複数のタイマーを同時に処理するには

いつもお世話になっています。
いま、タイマーを使ったアニメーションをやっているのですが、
SetTimer(VisualWnd,ID_YOKOUGOKI,200,NULL);
SetTimer(VisualWnd,ID_MOJIOKURI,20,NULL);
ようにすると、下のID_MOJIOKURIの部分しか処理されません。
case WM_TIMER:
switch(wParam){
case ID_YOKOUGOKI:
if(syouninkaiwa<13){
if(playeryoko==1){
playeryoko=2;
}else if(playeryoko==2){
playeryoko=3;
}else if(playeryoko==3){
playeryoko=4;
}else if(playeryoko==4){
playeryoko=1;
}
if(syouninyoko==1){
syouninyoko=2;
}else if(syouninyoko==2){
syouninyoko=3;
}else if(syouninyoko==3){
syouninyoko=4;
}else if(syouninyoko==4){
syouninyoko=1;
}
}
break;
case ID_MOJIOKURI:
if(syouninkaiwa==1){
mojiokuri+=1;
}
break;
}
InvalidateRect(VisualWnd,NULL,FALSE);
return 0;


また描画処理は
if(playeryoko==1){
BitBlt(hdcv, 250,132, 34, 32,
memdc[50], 0, 0, SRCCOPY);
}else if(playeryoko==2){
BitBlt(hdcv, 249,130, 34, 32,
memdc[55], 0, 0, SRCCOPY);
}else if(playeryoko==3){
BitBlt(hdcv, 250,132, 34, 32,
memdc[50], 0, 0, SRCCOPY);
}else if(playeryoko==4){
BitBlt(hdcv, 249,130, 34, 32,
memdc[56], 0, 0, SRCCOPY);
}
if(syouninyoko==1){
BitBlt(hdcv, 220,130, 29, 32,
memdc[51], 0, 0, SRCCOPY);
}else if(syouninyoko==2){
BitBlt(hdcv, 220,130, 29, 32,
memdc[57], 0, 0, SRCCOPY);
}else if(syouninyoko==3){
BitBlt(hdcv, 220,130, 29, 32,
memdc[51], 0, 0, SRCCOPY);
}else if(syouninyoko==4){
BitBlt(hdcv, 220,130, 29, 32,
memdc[58], 0, 0, SRCCOPY);
}
}else{
BitBlt(hdcv, 250,130, 34, 32,
memdc[50], 0, 0, SRCCOPY);
BitBlt(hdcv, 220,130, 29, 32,
memdc[51], 0, 0, SRCCOPY);
}
SetTimer(VisualWnd,ID_YOKOUGOKI,200,NULL);
SetTimer(VisualWnd,ID_MOJIOKURI,20,NULL);

if(syouninkaiwa == 0){
TextOut(hdcv,350,350,TEXT("push Enter"),lstrlen(TEXT("push Enter")));
}else if(syouninkaiwa == 1){
if(mojiokuri==1){
wsprintf(TEXT1,L"○");
}else if(mojiokuri==2){
wsprintf(TEXT1,L"○○");
}else if(mojiokuri==3){
wsprintf(TEXT1,L"○○○");
}else if(mojiokuri==4){
wsprintf(TEXT1,L"○○○○");
}else if(mojiokuri==5){
wsprintf(TEXT1,L"○○○○○");
}else if(mojiokuri==6){
wsprintf(TEXT1,L"○○○○○○");
}else if(mojiokuri==7){
wsprintf(TEXT1,L"○○○○○○○");
}else if(mojiokuri==8){
wsprintf(TEXT1,L"近頃、冒険者が多");
}
・・・・・・・・・・・・・・・・・・・・
TextOut(hdcv,20,240,TEXT1,lstrlen(TEXT1));
 
というふうです。
どちらが悪いのか分かりません。
ちなみに、タイマーの時間を同じにしたら、同時にできましたが、両方の処理が遅くなりました。
 
どのように解決したらよいのか教えてください。お願いします。

いつもお世話になっています。
いま、タイマーを使ったアニメーションをやっているのですが、
SetTimer(VisualWnd,ID_YOKOUGOKI,200,NULL);
SetTimer(VisualWnd,ID_MOJIOKURI,20,NULL);
ようにすると、下のID_MOJIOKURIの部分しか処理されません。
case WM_TIMER:
switch(wParam){
case ID_YOKOUGOKI:
if(syouninkaiwa<13){
if(playeryoko==1){
playeryoko=2;
}else if(playeryoko==2){
playeryoko=3;
}else if(playeryoko==3){
playeryoko=4;
}else if(playeryoko==4){
playeryoko=1;
}
if(syouninyoko==1){
syou...続きを読む

Aベストアンサー

コードから推察するに、原因は描画コード内のSetTimer関数の呼び出しだと思われます。

> SetTimer(VisualWnd,ID_YOKOUGOKI,200,NULL);
> SetTimer(VisualWnd,ID_MOJIOKURI,20,NULL);

まず、SetTimer関数(およびメッセージタイマー全体)の仕様を確認してください。
MSDN - SetTimer関数
http://msdn.microsoft.com/ja-jp/library/cc411200.aspx

SetTimer関数を呼び出すとuElapse引数で与えられた間隔で、WM_TIMERイベントを送り続ける仕様です。
nIDEventで識別されるタイマーが既に設定されていた場合、タイマーはリセットされます。

描画コードがWM_PAINTメッセージで処理されると仮定すると、
WM_TIMER→InavlidateRect()→WM_PAINT送出→SetTimer()が呼び出され、どちらのタイマもリセットされる。
ID_MOJIOKURIのタイマの方がID_YOKOUGOKIより高頻度なため、
高確率でID_MOJIOKURIが処理されているように見える…のではないかと思います。
提示されたコードからの推測ですので、確証はありませんが。

コードを見る限り、描画コード中のSetTimer関数呼び出しは不要に思えます。
ひとまず、描画コード中のSetTimer関数呼び出しは削除し、
タイマが不要になったらKillTimer関数を呼び出すように変更してみてはいかがでしょうか。


また、蛇足ですがメッセージタイマは55ms程度の精度しかありません。
ID_MOJIOKURIで20msを指定されていますが、実際にはその間隔での処理は期待できません。
文字送りですので、特に問題ないと思いますけど。

コードから推察するに、原因は描画コード内のSetTimer関数の呼び出しだと思われます。

> SetTimer(VisualWnd,ID_YOKOUGOKI,200,NULL);
> SetTimer(VisualWnd,ID_MOJIOKURI,20,NULL);

まず、SetTimer関数(およびメッセージタイマー全体)の仕様を確認してください。
MSDN - SetTimer関数
http://msdn.microsoft.com/ja-jp/library/cc411200.aspx

SetTimer関数を呼び出すとuElapse引数で与えられた間隔で、WM_TIMERイベントを送り続ける仕様です。
nIDEventで識別されるタイマーが既に設定されていた場合、タイ...続きを読む

Qエディットボックスの処理で画面がちらつきます。

VC++ 6.0 Win32APIにてダイアログベースのプログラムを作成しております。

ダイアログに18個のエディットボックスを配置しておりますが、そのエディットボックスのテキストを

SetDlgItemText()を使って全て空欄にすると(第3引数に””を指定)画面がちらつきます。

同ダイアログ内のリストコントロールがダブルクリックされた際のイベントを拾ってエディットボックスクリアの処理を実行しているのですが、ちらつきを抑える手法はありますでしょうか?

Aベストアンサー

予め WM_SETREDRAW で再描画を禁止しておいて、後で一括許可すると効果有りかもしれません。

Qエディットボックスのフォントを変えたい

MFCで作ったダイアログ上の他のコントロールはいじらずに、
エディットボックスのフォントだけを大きく変えたいのですが、
行間が変わらない為か、文字の下のほうが切れてしまいます。

色々試してみていますが、どうしても出来ません。

元のダイアログのフォントは12ptです。

OnInitDialog関数内で、
CFont m_font;(メンバ変数)に以下を設定し、
m_font.CreateFont( 20, 0, 0, 0, FW_SEMIBOLD, FALSE, FALSE, 0, SHIFTJIS_CHARSET, OUT_TT_PRECIS,CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,DEFAULT_PITCH | FF_DONTCARE, "MS P ゴシック" );

OnCtlColor関数内で、該当エディットボックスの場合だけ
pDC->SelectObject( &m_font );
しています。

CreateFontのパラメータが間違っているのでしょうか?

それとも、これら関数を呼び出す場所が間違っているのでしょうか?

ご回答お待ちしております。

MFCで作ったダイアログ上の他のコントロールはいじらずに、
エディットボックスのフォントだけを大きく変えたいのですが、
行間が変わらない為か、文字の下のほうが切れてしまいます。

色々試してみていますが、どうしても出来ません。

元のダイアログのフォントは12ptです。

OnInitDialog関数内で、
CFont m_font;(メンバ変数)に以下を設定し、
m_font.CreateFont( 20, 0, 0, 0, FW_SEMIBOLD, FALSE, FALSE, 0, SHIFTJIS_CHARSET, OUT_TT_PRECIS,CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,DEFAULT_PIT...続きを読む

Aベストアンサー

こんにちは。

Senna_FFさんの回答とかぶりますが、SetFontで出来ます。
CreateFontの下に下記の一行を追加してみてください。
質問のCreatoFontは正しく動作していました。
IDC_EDITはフォントを変更したいエディットボックスのIDを入れてください。


GetDlgItem(IDC_EDIT)->SetFont(&m_font);

QUpdateData( FALSE); による文字列データの表示更新(VC++6.0)

VC++の超初心者です.

UpdateData( FALSE );
を用いてエディットボックスの文字列の表示の更新を
試みているのですが,たとえば,以下のコードのようにボタンをクリックした際に文字列表示の更新を複数回行おうとするとうまくいきません.
具体的には一回目のUpdateData( FALSE );が反映されず二回目のUpdateData( FALSE );のみ反映されるという症状です.

なおm_mojiretsuはCstring型でエディットボックスのDDX用の変数です.

void CMyDlg::OnButton1()
{
DWORD p;

m_mojiretsu=_T("mojirstu1");
UpdateData( FALSE );

/*5秒の待ち*/
p=timeGetTime();
while(1){if((timeGetTime()-p)>5000) break;}

m_mojiretsu=_T("mojirstu1\r\nmojirstu2");
UpdateData( FALSE );

}


何か別の処理を行わなければいけないのでしょうか.
どこかに根本的なミスがあるのでしょうか.

VC歴3日程度で,右も左も分からず大変困っております.よろしくお願いします.

VC++の超初心者です.

UpdateData( FALSE );
を用いてエディットボックスの文字列の表示の更新を
試みているのですが,たとえば,以下のコードのようにボタンをクリックした際に文字列表示の更新を複数回行おうとするとうまくいきません.
具体的には一回目のUpdateData( FALSE );が反映されず二回目のUpdateData( FALSE );のみ反映されるという症状です.

なおm_mojiretsuはCstring型でエディットボックスのDDX用の変数です.

void CMyDlg::OnButton1()
{
DWORD p;

m_mojiretsu=_T("mojirst...続きを読む

Aベストアンサー

m_mojiretsu=_T("mojiretsu1");
UpdateData(FALSE);
UpdateWindow(); // <- これを追加

/*5秒の待ち*/
...

とすれば、ひとまず期待どおりの動作になると思います。

# こうするよりは、OnButton1() では変数を書き換えるべしと言う
# 自前のコマンドメッセージを投げるだけで、すぐに戻った方が
# お行儀は良いのですが...
# そこいらへんは追々調べたり試したりしてみて下さい。

Qリソースエディタでスタティックテキストの文字サイズの変更

 VisualStudio を使っています。
 リソースエディタで、作成したダイアログ・ボックス中に貼り付けた、
スタティックテキスト(Static Text)の文字サイズの変更を個別にしたいのです。

 ダイアログのプロパティには、フォントとサイズを変更できるようになっていますが、個々のスタティックテキストには、ありません。

 どうすれば、一番良いのでしょうか?
 教えてください。

 よろしくお願いします。

 

Aベストアンサー

WM_INITDIALOGの中でフォントを指定すればよいでしょう。
(MFCならCStatic::SetFont)

case WM_INITDIALOG:
{
HWND hStatic = GetDlgItem(hWnd , IDC_STATIC1 );
HFONT hFont = CreateFont(16,
0,
0,
0,
FW_REGULAR,
FALSE,
FALSE,
TRUE,
ANSI_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
PROOF_QUALITY,
DEFAULT_PITCH,
_T("MS ゴシック") );
SendMessage(hStatic,WM_SETFONT,(WPARAM)hFont, TRUE);
}

参考URL:http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200211/02110110.txt

QCStringの文字列検索&抜き出しについて

お世話になります。
///////////開発環境///////////
WinXP VisualStudio 2005 SDI MFC

以上の環境にてプログラムしています。

現在CString型の変数の中にある文字列操作について悩んでいます。

例えば、 CString Test(:program!~program@123.456 TEST :message);

このような内容が入ってるとします。
こんな時に例えばTESTを抜き出したい時にどうすればいいでしょうか?
なお、毎回TESTという文字列ではなくTEST2などの文字列が変わるもの
だとするとバイト数指定が出来なくて困っています。
バイト数指定しないでTESTのTのアドレスをGETしてそれを'\0'までを
切り抜くと:messageの部分まで取れてしまいます。
でもバイト指定が可変なので、出来ない・・。どうすればいいのでしょうか??
同様にmessageの部分も毎回変わっていてバイト数指定出来ません。
こちらの方は、文字列の最後から:を探していって:が見つかったらその
アドレスから'\0'までを切り出せばいいと思うのですが、もし
messageの部分に:mess:ageこういうメッセージが送られて来た時に、
:ageしか取れなくなり、本当はmess:ageを切り抜きたいのです。
せっかくMFCのCStringを使っているので、strtokやstr~などのC言語関数
は避けたいのですが、何かいい案ありますでしょうか??
ご教示宜しくお願いいたします。

お世話になります。
///////////開発環境///////////
WinXP VisualStudio 2005 SDI MFC

以上の環境にてプログラムしています。

現在CString型の変数の中にある文字列操作について悩んでいます。

例えば、 CString Test(:program!~program@123.456 TEST :message);

このような内容が入ってるとします。
こんな時に例えばTESTを抜き出したい時にどうすればいいでしょうか?
なお、毎回TESTという文字列ではなくTEST2などの文字列が変わるもの
だとするとバイト数指定が出来なくて困っています。
...続きを読む

Aベストアンサー

CStringクラスの持っているメソッドのFind と Mid を使う。

CStringT のメンバ (ATL/MFC)
http://msdn2.microsoft.com/ja-jp/library/abzc9989(VS.80).aspx
CStringT::Find (ATL/MFC)
http://msdn2.microsoft.com/ja-jp/library/hz2099kw(VS.80).aspx
CStringT::Mid (ATL/MFC)
http://msdn2.microsoft.com/ja-jp/library/b4c90k3d(VS.80).aspx


人気Q&Aランキング