ウィンドウの自動更新について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
クールくん

ウィンドウの自動更新について

#1

投稿記事 by クールくん » 9年前

コード:

		case WM_CREATE:
			SetTimer(hwnd,ID_MYTIMER,500,NULL);
			break;

		case WM_TIMER:
			InvalidateRect(hwnd,NULL,TRUE);
			UpdateWindow(hwnd);
			break;

		case WM_PAINT:
			rc = sqlite3_open("./db/data.db",&db);

			if(rc != SQLITE_OK)
			{
				MessageBox(NULL,"Error","ERROR!!",MB_OK);
			}
			else
			{
				memset(query,0,sizeof(query));
				query = "select NAME,FLAG from TABLE";
				sqlite3_prepare(db,query,strlen(query),&stmt,NULL);

				sqlite3_reset(stmt);

				hdc = BeginPaint(hwnd,&paint);

				memset(str,0,sizeof(str));
				i = 0;
				while(SQLITE_ROW == (rc = sqlite3_step(stmt)))
				{
					name = sqlite3_column_text(stmt,0);
					flag = sqlite3_column_int(stmt,2);

					sprintf(str,"%s                 %d",name,flag);
					TextOut(hdc,10,i*20,(LPCSTR)str,strlen(str));
					i++;
				}


				sqlite3_finalize(stmt);
				sqlite3_close(db);
			}
			break;
ウィンドウにSQLiteで取得したデータを描画させるプログラムです。
データの追加、削除、変更をする外部プログラムがあるのですが、
この外部プログラムにて、何らかのアクションがあったとしても
常に最新のデータを描画させ続けたいのですが、
このような書き方に何か問題はありますか?

描画、再描画は一応できているのですが、
このプログラムは常に起動させておきたいです。
昨晩から試に起動させっぱなしにして仕事に行って、いま帰宅したのですが、
画面が真っ白になっていました。
再描画の無限ループになっているので、PCへの負担は大きいと思いますが、
通常このような場合、どのように対処するのでしょうか?

同一のプログラム内でデータ更新のアクションがあれば、その瞬間にだけ再描画させるプログラムを書くことができますが、
外部プログラムとなると、よくわかりません。

アドバイスよろしくお願いします。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: ウィンドウの自動更新について

#2

投稿記事 by みけCAT » 9年前

少なくとも、
BeginPaint 関数を呼び出したときには、必ず対応する EndPaint 関数を呼び出さなければなりません。
とされているBeginPaint 関数を呼び出しているのに、EndPaint 関数を呼び出していないので、まずいでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

クールくん

Re: ウィンドウの自動更新について

#3

投稿記事 by クールくん » 9年前

みけCAT さんが書きました:少なくとも、
BeginPaint 関数を呼び出したときには、必ず対応する EndPaint 関数を呼び出さなければなりません。
とされているBeginPaint 関数を呼び出しているのに、EndPaint 関数を呼び出していないので、まずいでしょう。
確かにEndPaintを使っていなかったのは、まずかったです。
ご指摘ありがとうございます。

他に問題点や、改善した方がいいところがあったらお願いします。

YuO
記事: 947
登録日時: 14年前
住所: 東京都世田谷区

Re: ウィンドウの自動更新について

#4

投稿記事 by YuO » 9年前

思ったことをつらつらと。
  • SQLiteのデータが更新されていないなら,表示を更新する必要は無いですよね。
    表示するデータの量によりますが,前回のデータを保持した状態で,タイマー駆動でデータをとってきて,前回と比較,変化があれば再描画,という形にすると,描画の回数が減ります。
  • そもそもSQLiteはファイルベースなので,ファイルの変更を監視する,という方法でデータの変更をとってくることができるかもしれません。

クールくん

Re: ウィンドウの自動更新について

#5

投稿記事 by クールくん » 9年前

YuO さんが書きました:思ったことをつらつらと。
  • SQLiteのデータが更新されていないなら,表示を更新する必要は無いですよね。
    表示するデータの量によりますが,前回のデータを保持した状態で,タイマー駆動でデータをとってきて,前回と比較,変化があれば再描画,という形にすると,描画の回数が減ります。
  • そもそもSQLiteはファイルベースなので,ファイルの変更を監視する,という方法でデータの変更をとってくることができるかもしれません。
ご指摘ありがとうございます。
確かにファイルの変更を監視するとう方法がいいかもしれませんね。
通常このような処理をする場合には何を監視すればいいのでしょうか?
バイト数ですか?
それともバイナリでしょうか?

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: ウィンドウの自動更新について

#6

投稿記事 by みけCAT » 9年前

クールくん さんが書きました:通常このような処理をする場合には何を監視すればいいのでしょうか?
相手のプログラムの仕様にもよるかもしれませんが、タイムスタンプはどうでしょうか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: ウィンドウの自動更新について

#7

投稿記事 by みけCAT » 9年前

他に気になったことは、
クールくん さんが書きました:

コード:

				memset(query,0,sizeof(query));
				query = "select NAME,FLAG from TABLE";
どうせすぐに代入をするのに、わざわざ0 (ちなみに仕様上NULLとは限らない) で初期化しているのはなぜでしょうか?
クールくん さんが書きました:

コード:

					name = sqlite3_column_text(stmt,0);
					flag = sqlite3_column_int(stmt,2);

					sprintf(str,"%s                 %d",name,flag);
nameに十分長い文字列(へのポインタ)が代入された場合、バッファオーバーランを起こすリスクがあります。
クールくん さんが書きました:

コード:

					TextOut(hdc,10,i*20,(LPCSTR)str,strlen(str));
strはsprintfに渡されているので、char*、もしくは式中でchar*に変換される配列であると予想できます。
従って、明示的にTextOutAを呼び出し、LPCSTRへのキャストも消したほうがいい気がします。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

YuO
記事: 947
登録日時: 14年前
住所: 東京都世田谷区

Re: ウィンドウの自動更新について

#8

投稿記事 by YuO » 9年前

クールくん さんが書きました:確かにファイルの変更を監視するとう方法がいいかもしれませんね。
通常このような処理をする場合には何を監視すればいいのでしょうか?
Windowsに関してならば,ReadDirectoryChangesWFindFirstChangeNotificationといった,ファイルシステムの変更を通知してくれるAPIがありますので,これを使います。
通知内容は,FILE_NOTIFY_CHANGE_LAST_WRITEだけでも十分だと思います。

閉鎖

“C言語何でも質問掲示板” へ戻る