かなり変な所ではまってしまってしまいました・・・。
以前のプログラムでは問題なく開いていたダイアログを
開こうとすると不正な処理で落ちてしまい、デバックを
してみるとStack Overflowで落ちていることが分かったのですが
過去に作っていたプログラムと問題の部分を照らし合わせても
何も変わりがないのでどうしてなのかなぁ・・・と
詰まってしまっているところです・・・。
以前のプログラムのソースコード
http://angelteatime.punyu.net/knot/file/mview005.lzh
現在の最新ソースコード
http://angelteatime.punyu.net/knot/file/mview006.lzh
問題なのはWndProcのWM_COMMANDで呼び出している
IDM_OPEN:で開くダイアログ(添付ファイルを開く)を
開こうとするとStack Overflowで落ちます。
たぶん開放していない変数はないと思うのですが・・・・。
原因を教えていただけないでしょうか?
ローカル変数のメモリ使用量が多すぎるからでしょ。
環境はVC++6.0、WindowsXP Home SP2です。
ちなみに他のダイアログの表示(新規メール作成、メールの設定、
バージョン表示など)では落ちずに表示できるという変な状態です。
あとその中で使用しているCenterWindow(自作関数)関数の中で
戻り値で使用しているSetWindowPosの実行でStack Overflowが
起きていて、その関数をコメント化するとダイアログは表示
されるけれど閉じるボタン(ただEndDialogを呼んでいるだけ)を
押すとStack Overflowになるというという変な状態です。
部分的にコードを載せておきます。
// ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
int iClickNo, Ret;
static int iStatusWy;
unsigned long datasz, Result, datatype; // レジストリ用の変数
static HWND hEdit, hList; // コントロールハンドル
RECT rc; // RECT構造体
POINT pt; // POINT構造体
DWORD dwStyle; // ウィンドウスタイル
LPNMHDR lpnmhdr; // ヘッダハンドラ
LPNMLISTVIEW lpnmlv; // リストビューハンドラ
HKEY hRegKey; // レジストリハンドラ
HMENU hMenu, hPMenu; // メニューハンドル
INITCOMMONCONTROLSEX ic; // コモンコントロール
char szFileName[TEMP_MAX], szSubject[TEMP_MAX];
switch(msg){
case WM_CREATE:
NMailSetParameter(0, TEMP_MAX, 0);
NMailInitializeWinSock();
ic.dwSize = sizeof(INITCOMMONCONTROLSEX);
ic.dwICC = ICC_BAR_CLASSES | ICC_LISTVIEW_CLASSES;
InitCommonControlsEx(&ic);
hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_WANTRETURN | WS_VSCROLL | WS_HSCROLL | ES_AUTOVSCROLL | ES_AUTOHSCROLL, 0, 0, 0, 0, hWnd, (HMENU)ID_EDIT, hInst, NULL);
SendMessage(hEdit, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), 0);
hList = CreateWindowEx(WS_EX_CLIENTEDGE, WC_LISTVIEW, "", WS_CHILD | WS_VISIBLE | WS_BORDER | LVS_REPORT, 0, 0, 0, 0, hWnd, (HMENU)ID_LISTVIEW, hInst, NULL);
dwStyle = ListView_GetExtendedListViewStyle(hList);
dwStyle |= LVS_EX_FULLROWSELECT | LVS_EX_HEADERDRAGDROP;
ListView_SetExtendedListViewStyle(hList, dwStyle);
InsertColumn(hList);
hStatus = CreateStatusWindow(WS_CHILD | WS_VISIBLE, "", hWnd, ID_STATUS);
GetWindowRect(hStatus, &rc);
iStatusWy = rc.bottom - rc.top;
RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Angelic Software\\MailViewer", 0, "MailViewer", 0, KEY_ALL_ACCESS, NULL, &hRegKey, &Result);
if(Result == REG_CREATED_NEW_KEY){
// レジストリへの新規作成処理
RegSetValueEx(hRegKey, "Smtp Address", 0, REG_SZ, (LPBYTE)szSmtpServer, strlen(szSmtpServer)+1);
RegSetValueEx(hRegKey, "Pop3 Address", 0, REG_SZ, (LPBYTE)szPopServer, strlen(szPopServer)+1);
RegSetValueEx(hRegKey, "Mail Address", 0, REG_SZ, (LPBYTE)szMailAddr, strlen(szMailAddr)+1);
RegSetValueEx(hRegKey, "User Name", 0, REG_SZ, (LPBYTE)szUserName, strlen(szUserName)+1);
RegSetValueEx(hRegKey, "From Name", 0, REG_SZ, (LPBYTE)szName, strlen(szName)+1);
RegSetValueEx(hRegKey, "Password", 0, REG_SZ, (LPBYTE)szPass, strlen(szPass)+1);
RegSetValueEx(hRegKey, "APop", 0, REG_DWORD, (LPBYTE)&bApop, sizeof(DWORD));
RegSetValueEx(hRegKey, "Pop Before SMTP", 0, REG_DWORD, (LPBYTE)&bPSmtp, sizeof(DWORD));
RegSetValueEx(hRegKey, "Server Mail Del", 0, REG_DWORD, (LPBYTE)&bSMailDel, sizeof(DWORD));
}
else{
// レジストリからの読出し処理
datasz = 256;
RegQueryValueEx(hRegKey, "Smtp Address",NULL,&datatype,(LPBYTE)szSmtpServer,&datasz);
datasz = 256;
RegQueryValueEx(hRegKey, "Mail Address",NULL,&datatype,(LPBYTE)szMailAddr,&datasz);
datasz = 256;
RegQueryValueEx(hRegKey, "Pop3 Address",NULL,&datatype,(LPBYTE)szPopServer,&datasz);
datasz = 256;
RegQueryValueEx(hRegKey, "User Name",NULL,&datatype,(LPBYTE)szUserName,&datasz);
datasz = 256;
RegQueryValueEx(hRegKey, "Password",NULL,&datatype,(LPBYTE)szPass,&datasz);
datasz = 256;
RegQueryValueEx(hRegKey, "From Name",NULL,&datatype,(LPBYTE)szName,&datasz);
datasz = sizeof(DWORD);
RegQueryValueEx(hRegKey, "APop",NULL,&datatype,(LPBYTE)&bApop,&datasz);
datasz = sizeof(DWORD);
RegQueryValueEx(hRegKey, "Pop Before SMTP",NULL,&datatype,(LPBYTE)&bPSmtp,&datasz);
datasz = sizeof(DWORD);
RegQueryValueEx(hRegKey, "Server Mail Del",NULL,&datatype,(LPBYTE)&bSMailDel,&datasz);
}
RegCloseKey(hRegKey);
// 起動時のバグを回避
No = -1;
// ローカルに保存しているメール一覧を表示
SetLocalMail(hList);
break;
case WM_SIZE:
MoveWindow(hList, 0, 0, LOWORD(lParam), (HIWORD(lParam) - iStatusWy) / 2, TRUE);
MoveWindow(hEdit, 0, (HIWORD(lParam) - iStatusWy) / 2, LOWORD(lParam), (HIWORD(lParam) - iStatusWy) / 2, TRUE);
sb_size = LOWORD(lParam) - 120;
SendMessage(hStatus, WM_SIZE, wParam, lParam);
break;
case WM_NOTIFY:
lpnmhdr = (LPNMHDR)lParam;
// 新しいコード
if(lpnmhdr->hwndFrom == hList){
switch(lpnmhdr->code){
// シングルクリックの時
case NM_CLICK:
lpnmlv = (LPNMLISTVIEW)lParam;
No = iClickNo = lpnmlv->iItem;
// クリックした番号が-1の時はメールを表示しない
if(iClickNo == -1){
break;
}
// メールデータファイル名を取得する
ListView_GetItemText(hList, iClickNo, 4, szFileName, sizeof(szFileName));
// メールファイルを開く
Read_MailData(szFileName, hEdit);
break;
case NM_RCLICK:
lpnmlv = (LPNMLISTVIEW)lParam;
iClickNo = lpnmlv->iItem;// + 1;
// クリックした番号が-1の時はメニューを表示しない
if(iClickNo == -1){
break;
}
// 右クリックメニューを開く
GetCursorPos(&pt);
CreatePopupMenu();
hPMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_MENU2));
hMenu = GetSubMenu(hPMenu, 0);
TrackPopupMenu(hMenu,TPM_LEFTALIGN|TPM_LEFTBUTTON,pt.x,pt.y,0,hWnd,NULL);
DestroyMenu(hMenu);
break;
}
}
break;
// メニューを選択した時の説明表示(ステータスバー)
case WM_MENUSELECT:
switch (LOWORD(wParam)){
case IDM_OPEN:
SendMessage(hStatus, SB_SETTEXT, 0 | 0, (LPARAM)szTipText[0]);
break;
case IDM_SAVE:
SendMessage(hStatus, SB_SETTEXT, 0 | 0, (LPARAM)szTipText[1]);
break;
case IDM_PAGEINF:
SendMessage(hStatus, SB_SETTEXT, 0 | 0, (LPARAM)szTipText[2]);
break;
case IDM_PRINT:
SendMessage(hStatus, SB_SETTEXT, 0 | 0, (LPARAM)szTipText[3]);
break;
case IDM_EXIT:
SendMessage(hStatus, SB_SETTEXT, 0 | 0, (LPARAM)szTipText[4]);
break;
case IDM_NEW:
SendMessage(hStatus, SB_SETTEXT, 0 | 0, (LPARAM)szTipText[5]);
break;
case IDM_RCVMAIL:
SendMessage(hStatus, SB_SETTEXT, 0 | 0, (LPARAM)szTipText[6]);
break;
case IDM_REPLY:
SendMessage(hStatus, SB_SETTEXT, 0 | 0, (LPARAM)szTipText[7]);
break;
case IDM_DELETE:
SendMessage(hStatus, SB_SETTEXT, 0 | 0, (LPARAM)szTipText[8]);
break;
case IDM_HEADER:
SendMessage(hStatus, SB_SETTEXT, 0 | 0, (LPARAM)szTipText[9]);
break;
case IDM_SET:
SendMessage(hStatus, SB_SETTEXT, 0 | 0, (LPARAM)szTipText[10]);
break;
case IDM_HELP:
SendMessage(hStatus, SB_SETTEXT, 0 | 0, (LPARAM)szTipText[11]);
break;
case IDM_ABOUT:
SendMessage(hStatus, SB_SETTEXT, 0 | 0, (LPARAM)szTipText[12]);
break;
default:
SendMessage(hStatus, SB_SETTEXT, 0 | 0, (LPARAM)"");
break;
}
break;
// メニューを抜けた時の処理
case WM_EXITMENULOOP:
SendMessage(hStatus, SB_SETTEXT, 0 | 0, (LPARAM)"");
break;
case WM_COMMAND:
switch(LOWORD(wParam)){
case IDM_NEW:
// 新規
DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG4), hWnd, (DLGPROC)NewMailProc);
break;
case IDM_OPEN:
// 開く
DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG5), hWnd, (DLGPROC)AttachFileProc);
break;
case IDM_SAVE:
// 保存
//if(No > 0){
if(No >= 0){
WriteMailFile(hWnd);
}
break;
case IDM_PRINT:
// 印刷
//if(No > 0){
if(No >= 0){
// メールの件名を取得
ListView_GetItemText(hList, No, 0, szSubject, sizeof(szSubject));
wsprintf(strMsg, "「%s」を印刷しますか?", szSubject);
//wsprintf(strMsg, "%d番目のメールを印刷しますか?", No);
Ret = MessageBox(hWnd, strMsg, "印刷の確認", MB_YESNO | MB_ICONQUESTION);
if(Ret == IDYES){
MPrint(hWnd);
}
}
break;
case IDM_RCVMAIL:
// メールの受信
// エディットボックスの内容を削除する
SetWindowText(hEdit, "");
// 基本設定がされていないとき
if(strcmp(szPopServer, "") == 0 || strcmp(szUserName, "") == 0 || strcmp(szPass, "") == 0){
MessageBox(hWnd, "メール受信の設定ができていません", "Mail Viewer", MB_OK | MB_ICONSTOP);
break;
}
// まずはPOP3 サーバーに接続
if((s = NMailPop3Connect(szPopServer)) != INVALID_SOCKET){
// POP3 認証 & メールタイトル一覧表示
if(List_Mail(s, szPopServer, szUserName, szPass, hList, hStatus) >= 0){
NMailPop3Close(s);
}
else{
MessageBox(hWnd, "認証に失敗しました", "Mail Viewer", MB_OK | MB_ICONSTOP);
DestroyWindow(hProgress);
NMailPop3Close(s);
}
}
else{
MessageBox(hWnd, "接続に失敗しました", "Mail Viewer", MB_OK | MB_ICONSTOP);
DestroyWindow(hProgress);
NMailPop3Close(s);
}
break;
case IDM_REPLY:
// メールの返信
//if(No > 0){
if(No >= 0){
bReply = TRUE;
DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG4), hWnd, (DLGPROC)NewMailProc);
}
break;
case IDM_DELETE:
// メールの削除
//if(No > 0){
if(No >= 0){
// テキストボックスを初期化
SetWindowText(hEdit, "");
// メールデータファイル名を取得する
ListView_GetItemText(hList, No, 4, szFileName, sizeof(szFileName));
ListView_GetItemText(hList, No, 0, szSubject, sizeof(szSubject));
wsprintf(strMsg, "「%s」を削除しますか?", szSubject);
//wsprintf(strMsg, "%d番目のメールを削除しますか?", No);
Ret = MessageBox(hWnd, strMsg, "削除の確認", MB_YESNO | MB_ICONQUESTION);
if(Ret == IDYES){
// 選択したメールを削除
if(!DeleteFile(szFileName)){
// 削除に失敗したとき
MessageBox(hWnd, "削除に失敗しました", "MailViewer", MB_OK | MB_ICONSTOP);
break;
}
else{
// 削除が出来たとき
//wsprintf(strMsg,"%d件目を削除しました\n", No);
wsprintf(strMsg,"メールを削除しました\n", No);
MessageBox(hWnd, strMsg, "MailViewer", MB_OK | MB_ICONINFORMATION);
}
// 受信メール一覧の更新
SetLocalMail(hList);
// 選択したメールを削除
/*if((s = NMailPop3Connect(szPopServer)) != INVALID_SOCKET){
if(NMailPop3Authenticate(s, szUserName, szPass, bApop) >= 0){
if(NMailPop3DeleteMail(s, No) >= 0){
wsprintf(strMsg,"%d件目を削除しました\n", No);
MessageBox(hWnd, strMsg, "MailViewer", MB_OK | MB_ICONINFORMATION);
}
else{
MessageBox(hWnd, "削除に失敗しました", "MailViewer", MB_OK | MB_ICONSTOP);
}
}
NMailPop3Close(s);
// リストの更新
SendMessage(hWnd, WM_COMMAND, IDM_RCVMAIL, 0);
}
else{
MessageBox(hWnd, "POP3の接続に失敗しました", "MailViewer", MB_OK | MB_ICONINFORMATION);
}*/
}
}
break;
case IDM_HEADER:
// ヘッダ表示
//if(No > 0){
if(No >= 0){
DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG3), hWnd, (DLGPROC)HeaderProc);
SendMessage(hStatus, SB_SETTEXT, 0 | 0, (LPARAM)"");
}
break;
case IDM_SET:
// メールの設定
DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG1), hWnd, (DLGPROC)MailSetProc);
SendMessage(hStatus, SB_SETTEXT, 0 | 0, (LPARAM)"");
break;
case IDM_EXIT:
SendMessage(hWnd, WM_CLOSE, 0, 0);
break;
case IDM_HELP:
HtmlHelp(hWnd, "mailviewer.chm::/00.html > mailviewer01", HH_DISPLAY_TOC, NULL);
break;
case IDM_ABOUT:
VersionNo = NMailGetVersion();
DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG2), hWnd, (DLGPROC)AboutProc);
SendMessage(hStatus, SB_SETTEXT, 0 | 0, (LPARAM)"");
break;
}
return 0;
case WM_CLOSE:
// HTMLヘルプが開いていたら閉じる
if(HtmlHelp(hWnd, "mailviewer.chm", HH_GET_WIN_HANDLE, (DWORD)"mailviewer01")){
HtmlHelp(NULL, NULL, HH_CLOSE_ALL, 0);
}
// レジストリへの書き込み
RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Angelic Software\\MailViewer", 0, "MailViewer", 0, KEY_ALL_ACCESS, NULL, &hRegKey, &Result);
RegSetValueEx(hRegKey, "Smtp Address", 0, REG_SZ, (LPBYTE)szSmtpServer, strlen(szSmtpServer)+1);
RegSetValueEx(hRegKey, "Pop3 Address", 0, REG_SZ, (LPBYTE)szPopServer, strlen(szPopServer)+1);
RegSetValueEx(hRegKey, "From Name", 0, REG_SZ, (LPBYTE)szName, strlen(szName)+1);
RegSetValueEx(hRegKey, "Mail Address", 0, REG_SZ, (LPBYTE)szMailAddr, strlen(szMailAddr)+1);
RegSetValueEx(hRegKey, "User Name", 0, REG_SZ, (LPBYTE)szUserName, strlen(szUserName)+1);
RegSetValueEx(hRegKey, "Password", 0, REG_SZ, (LPBYTE)szPass, strlen(szPass)+1);
RegSetValueEx(hRegKey, "APop", 0, REG_DWORD, (LPBYTE)&bApop, sizeof(DWORD));
RegSetValueEx(hRegKey, "Pop Before SMTP", 0, REG_DWORD, (LPBYTE)&bPSmtp, sizeof(DWORD));
RegSetValueEx(hRegKey, "Server Mail Del", 0, REG_DWORD, (LPBYTE)&bSMailDel, sizeof(DWORD));
RegCloseKey(hRegKey);
// ウィンドウハンドルを破棄
DestroyWindow(hWnd);
DestroyWindow(hStatus);
DestroyWindow(hEdit);
break;
case WM_DESTROY:
HtmlHelp(NULL, NULL, HH_UNINITIALIZE, dwCookie);
NMailEndWinSock();
PostQuitMessage(0);
break;
default:
return(DefWindowProc(hWnd, msg, wParam, lParam));
}
return (0L);
}
(省略)
// 添付ファイルを展開して保存ダイアログ
LRESULT CALLBACK AttachFileProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
HWND hList, hFDEdit, hFBtn, hFDBtn;
BROWSEINFO bi;
ITEMIDLIST *lpid;
HRESULT hr;
LPMALLOC pMalloc = NULL; // IMallocへのポインタ
BOOL bDir = FALSE;
HANDLE hFile; // ファイルハンドル
HGLOBAL hMem; // グローバルハンドル
DWORD dwFSizeHigh, dwFSize, dwAccBytes; // バイト数
char *lpszBuf; // ファイルバッファ
char f_id[TEMP_MAX], *PertId; // 分割メールのID
int no; // 添付ファイルの個数
int ret; // 戻り値
// 添付メール展開用変数
char subject[TEMP_MAX], date[TEMP_MAX], from[TEMP_MAX], header[TEMP_MAX], body[TEMP_MAX];
char FileName[TEMP_MAX], Temp[NMAIL_ATTACHMENT_TEMP_SIZE];
switch(msg){
case WM_INITDIALOG:
CenterWindow(hDlg, hParent);
hList = GetDlgItem(hDlg, IDC_LIST1);
hFDBtn = GetDlgItem(hDlg, IDC_FILEBTN);
hFBtn = GetDlgItem(hDlg, IDC_BUTTON1);
return TRUE;
case WM_COMMAND:
switch(LOWORD(wParam)){
case IDC_BUTTON1:
AttachFileOpen(hDlg, szAtFile, szAtFileName);
// ファイルを開く
hFile = CreateFile(szAtFile, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile == INVALID_HANDLE_VALUE){
MessageBox(hDlg, "ファイルをオープンできません", "Error", MB_OK);
return FALSE;
}
// ファイルサイズを調べる
dwFSize = GetFileSize(hFile, &dwFSizeHigh);
if(dwFSizeHigh != 0){
MessageBox(hDlg, "ファイルが大きすぎます", "Error", MB_OK);
CloseHandle(hFile);
return FALSE;
}
// ファイルを読み込むためのメモリ領域を確保
hMem = GlobalAlloc(GHND, dwFSize + 1);
if(hMem == NULL){
MessageBox(hDlg, "メモリを確保できません", "Error", MB_OK);
CloseHandle(hFile);
return FALSE;
}
// メモリ領域をロックしてファイルを読み込む
lpszBuf = (char *)GlobalLock(hMem);
ReadFile(hFile, lpszBuf, dwFSize, &dwAccBytes, NULL);
lpszBuf[dwFSize] = '\0';
// szAtFileDataのメモリ領域を確保する
szAtFileData = (char *)malloc(sizeof(char) * dwFSize);
if(szAtFileData == NULL){
MessageBox(hDlg, "メモリ確保に失敗しました", "メモリ確保失敗", MB_OK |MB_ICONSTOP);
return FALSE;
}
// メールファイルの中身をコピーする
strcpy((char *)szAtFileData, lpszBuf);
// ファイルを閉じる
CloseHandle(hFile);
GlobalUnlock(hMem);
GlobalFree(hMem);
// ファイルが添付されているかを確認する
if((no = NMailAttachmentFileStatus(szAtFileData, f_id, TEMP_MAX)) != NMAIL_NO_ATTACHMENT_FILE){
if(no == 1){
PertId = f_id;
}
hList = GetDlgItem(hDlg, IDC_LIST1);
if(no == 0 || PertId == f_id){
SendMessage(hList, LB_INSERTSTRING, (WPARAM)0, (LPARAM)szAtFile);
SendMessage(hList, LB_SETCURSEL, (WPARAM)0, 0L);
EnableWindow(GetDlgItem(hDlg, IDOK), TRUE);
}
}
else{
// 添付ファイルがないのでメッセージを出して終了
MessageBox(hDlg, "このメールに、添付ファイルはありません", "添付ファイルなし", MB_OK |MB_ICONINFORMATION);
}
return TRUE;
case IDC_FILEBTN:
memset(&bi, 0, sizeof(BROWSEINFO));
bi.hwndOwner = hDlg;
bi.lpfn = SHMyProc;
bi.ulFlags = BIF_EDITBOX | BIF_STATUSTEXT | BIF_VALIDATE;
bi.lpszTitle = "展開先ディレクトリ指定";
lpid = SHBrowseForFolder(&bi);
if(lpid == NULL){
return FALSE;
}
else{
hr = SHGetMalloc(&pMalloc);
if(hr == E_FAIL){
MessageBox(hDlg, "SHGetMalloc Error", "Error", MB_OK);
return FALSE;
}
SHGetPathFromIDList(lpid, szDir);
if(szDir[strlen(szDir) - 1] != '\\'){
strcat(szDir, "\\");
}
hFDEdit = GetDlgItem(hDlg, IDC_EDIT1);
// 展開先フォルダをセットする
SetWindowText(hFDEdit, szDir);
pMalloc->Free(lpid);
pMalloc->Release();
bDir = TRUE;
}
return TRUE;
case IDOK:
// 添付ファイルの展開
ret = NMailAttachmentFileFirst(Temp, subject, date, from, header, body, szDir, FileName, szAtFileData, NULL);
if(ret == NMAIL_SUCCESS){
NMailAttachmentFileClose(Temp);
wsprintf(strMsg, "%sに%sを展開しました。", szDir, FileName);
MessageBox(hDlg, strMsg, "Mail Viewer", MB_OK | MB_ICONINFORMATION);
}
// メモリの解放
free(szAtFileData);
EndDialog(hDlg, IDOK);
return TRUE;
case IDCANCEL:
EndDialog(hDlg, IDOK);
return TRUE;
default:
return FALSE;
}
default:
return FALSE;
}
return TRUE;
}
(省略)
// ダイアログを中央に表示する
BOOL CenterWindow(HWND hwndChild, HWND hwndParent)
{
BOOL bResult;
RECT rcChild, rcParent, rcWorkArea;
int wChild, hChild, wParent, hParent;
int xNew, yNew;
GetWindowRect(hwndChild,&rcChild);
wChild = rcChild.right - rcChild.left;
hChild = rcChild.bottom - rcChild.top;
if(hwndParent){
GetWindowRect(hwndParent,&rcParent);
}
else{
GetWindowRect(GetDesktopWindow(),&rcParent);
}
wParent = rcParent.right - rcParent.left;
hParent = rcParent.bottom - rcParent.top;
bResult = SystemParametersInfo(SPI_GETWORKAREA,sizeof(RECT),&rcWorkArea,0);
if(!bResult){
rcWorkArea.left = rcWorkArea.top = 0;
rcWorkArea.right = GetSystemMetrics(SM_CXSCREEN);
rcWorkArea.bottom = GetSystemMetrics(SM_CYSCREEN);
}
xNew = rcParent.left + ((wParent-wChild) / 2);
if(xNew < rcWorkArea.left){
xNew = rcWorkArea.left;
}
else if((xNew+wChild) > rcWorkArea.right){
xNew = rcWorkArea.right - wChild;
}
yNew = rcParent.top + ((hParent-hChild) / 2);
if(yNew < rcWorkArea.top){
yNew = rcWorkArea.top;
}
else if((yNew+hChild) > rcWorkArea.bottom){
yNew = rcWorkArea.bottom - hChild;
}
return SetWindowPos(hwndChild, HWND_TOP, xNew, yNew, 0, 0, SWP_NOSIZE);
}
コンパイルの指定でスタックを増やすだけで解決するんじゃない。
VC++6.0のスタックの増やし方は知らん。
サブルーチンに分けろよ。
ダイアログ出すときに使わないローカル変数のせいでスタックを大量に使っている。
長いソースを貼られても、ちょっと読んでる時間はないです。
とりあえず…
ウィンドゥプロシージャ内の変数、もう少し整理してください。
WM_CREATEでつかわないモノまで確保されることになります。
case文の後にブロック切って、その中で使うモノだけにすれば
プロシージャ内でのローカル変数の使用量は減らせるハズです。
# 猫でも…はブロック分けになっていないのか…
InitCommonControlsEx()はWinMain()でやれば十分では?
# VCではデフォルトのスタックサイズは1Mほどです。
# リンカオプションで拡張できますが、配列など大きなモノを使う場合は
# ヒープから取るようにした方がいいです。
## MAX_PATHな配列5つくらいはローカルでよく取りますけど…
とりあえずWndProc内のコードでサブルーチン化可能な
コードをサブルーチン化(レジストリのところとか)して
InitCommonControlsEx()など別にWndProcでしなくても
OKな初期化関数をWinMainに移動したり、無駄使いしていた
WndProcのszFileName[TEMP_MAX]とszSubject[TEMP_MAX]を
グローバルに移動(既にこの名前の変数が存在するので
名前を変えて)した事により、添付ファイル取り出し用の
ダイアログを開こうとして強制終了(実際はStack Overflow)する
現象が解決しました。
私のプログラムの知識が足りないばかりにご迷惑をおかけして
本当に申し訳ありませんです。
もう少し工夫出来そうな所を探して、コードをもう少し
見やすいように作っていこうと思います。
ありがとうございました。
ツイート | ![]() |