2025
01
18
2008
09
25
CSocket+CSockFile+CArchiveの注意点
CArchive クラスが提供するメンバ関数 IsBufferEmpty は、CSocket クラス専用です。たとえば、バッファに複数のデータ メッセージがある場合は、処理を繰り返してすべてのデータを読み出してバッファを空にする必要があります。バッファを空にしないと、次のデータ受信通知が無期限に遅れることになります。IsBufferEmpty を使うと、すべてのデータを確実に取得できます。
2008/09/25 (Thu.) Trackback() Comment(0) MFC
2008
09
24
MFCでのメモリリークの検出方法
MFCでのメモリリークの検出方法
MSDN HTMLヘルプ Version 4.74.8702 において、キーワードタブから「メモリ割り当ての追跡」にちょっとした情報は載っていますが、実際にどのように書き込んだり使ったりしたらいいのかの例が 見当たりません。具体的には次のようにすれば検出できます。
#ifdef __AFX_H__ // MFCのウィンドウを使う場合に限定しています #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #endif以上のコードを、すべてのソースコード (*.cpp) のヘッダファイルをインクルードしたあとに追加します。
とりあえずこれを追加して実行して普通に終了させてみてください。もし、プログラムでメモリリークが起こっているのであれば、次のような出力がアウトプットウィンドウのデバッグの欄に表示されます。
(半角カタカナは全角カタカナに修正してあります)スレッド 0x624 終了、終了コード 0 (0x0)。 Detected memory leaks! Dumping objects -> G:\Projects\DispBMPDoc.cpp(87) : {158} normal block at 0x014D0040, 921602 bytes long. Data: < > 00 FF 00 00 FF 00 00 FF 00 00 FF 00 00 FF 00 00 G:\Projects\DispBMPDoc.cpp(86) : {157} normal block at 0x00346E78, 40 bytes long. Data: <( > 28 00 00 00 80 02 00 00 E0 01 00 00 01 00 18 00 Object dump complete. スレッド 0x620 終了、終了コード 0 (0x0)。 プログラム 'G:\Projects\Debug\DispBMP.exe' はコード 0 (0x0) で終了しました。始めてみる場合は、何のことだかさっぱり分からないと思います。意味としては次のようになります。
Detected memory leaks!
メモリリークを検出しました。
Dumping objects ->
メモリリークしたブロックを表示していきます。
G:\Projects\DispBMPDoc.cpp(87) : {158} normal block at 0x014D0040, 921602 bytes long.
G:\Projects\DispBMPDoc.cppというファイルの87行目で割り当てられたブロックです。
プログラムの実行開始から158番目に割り当てられたブロックです。
割り当てられた番地は、0x014D0040番地です。(OSがWin9x、WinNTによっても値が変わってきます)
割り当てられたサイズは、921602 バイトです。Data: < > 00 FF 00 00 FF 00 00 FF 00 00 FF 00 00 FF 00 00
割り当てられていたブロックに入っているデータの先頭部分が表示されます。
Object dump complete.
メモリリークしたブロックの表示が終わりました。
このような感じで表示されるので、とりあえずファイル名と行番号からメモリを割り当てている場所はわかります。
メモリ開放が行われていないはずなので、追加してください。
2008/09/24 (Wed.) Trackback() Comment(0) MFC
2008
09
12
ダイアログアプリのcppUnitテスト
最初そうやってリンクしようか悩んだが、ダイアログアプリ(本体)全体をlibにして
(できるんですねぇ)、リンクしてテスト用コンソールアプリからテストすることにした。
とりあえず、できた。
テスト用に構成を作って、その場合は、libを生成するようにしたためテストするために
構成を変えてビルドしなくちゃいけないのが面倒だ。
ってかこんなんでいいのかなぁ
2008/09/12 (Fri.) Trackback() Comment(0) MFC
2008
09
02
ダイアログのタスクトレイ常駐化
BOOL CDlg::OnInitDialog(){
// タスクトレイ化
m_stNotifyIcon.cbSize = sizeof(NOTIFYICONDATA);
m_stNotifyIcon.uID = 0;
m_stNotifyIcon.hWnd = m_hWnd;
m_stNotifyIcon.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
m_stNotifyIcon.hIcon = AfxGetApp()->LoadIcon( IDR_MAINFRAME );
m_stNotifyIcon.uCallbackMessage = NIM_TRAYNOTIFY;
_tcscpy_s( m_stNotifyIcon.szTip, _T("タスクトレイアプリのテスト"));
::Shell_NotifyIcon( NIM_ADD, &m_stNotifyIcon );
// タスクトレイ化
}
LRESULT CDlg::OnTrayNotify(WPARAM wParam, LPARAM lParam )
{
// TODO: ここにメッセージ ハンドラ コードを追加します。
switch(lParam) {
case WM_LBUTTONDOWN:
if (::IsIconic(m_hWnd)) {
ShowWindow(SW_SHOWNORMAL);
SetForegroundWindow();
}
else {
ShowWindow(SW_MINIMIZE); // IsIconicで判定するためにはMINIMIZEする
ShowWindow(SW_HIDE);
}
break;
default:
break;
}
return 0;
}
2008/09/02 (Tue.) Trackback() Comment(0) MFC
2008
09
02
ダイアログ非表示
*****ダイアログを生成部分で非表示にする処理をコールする*****
//ダイアログ表示
//INT_PTR nResponse = dlg.DoModal();
// タスクトレイ化のためにダイアログ表示修正
dlg.Create(IDD_DIALOG);
dlg.ShowWindow(SW_MINIMIZE);
dlg.ShowWindow(SW_HIDE);
INT_PTR nResponse = dlg.RunModalLoop(MLF_NOKICKIDLE);
OnActivateやOnInitDialogで
dlg.ShowWindow(SW_MINIMIZE);
dlg.ShowWindow(SW_HIDE);
を呼んでもまったく駄目だった。Dlg生成前だから???
2008/09/02 (Tue.) Trackback() Comment(0) MFC