15.對話框啟動即隐藏
添加 WM_SHOWWINDOW 的消息映射
void CTest6Dlg::OnShowWindow(BOOL bShow, UINT nStatus)
{
if ( GetStyle() & WS_VISIBLE )
{
CDialog::OnShowWindow(bShow, nStatus);
}
else
{
long Style = ::GetWindowLong(*this, GWL_STYLE);
::SetWindowLong(*this, GWL_STYLE, Style | WS_VISIBLE);
CDialog::OnShowWindow(SW_HIDE, nStatus);
}
}
16.對話框自動停靠在螢幕邊
const int DETASTEP = 50;
BOOL AdjustPos(CWnd *pWnd, CRect* lpRect)
{
//自動靠邊
int iSX = GetSystemMetrics(SM_CXFULLSCREEN);
int iSY = GetSystemMetrics(SM_CYFULLSCREEN);
RECT rWorkArea;
BOOL bResult = SystemParametersInfo(SPI_GETWORKAREA, sizeof(RECT), &rWorkArea, 0);
CRect rcWA;
if ( !bResult )
{
//如果調用不成功就利用GetSystemMetrics擷取螢幕面積
rcWA = CRect(0,0,iSX,iSY);
}
else
rcWA = rWorkArea;
int iX = lpRect->left;
int iY = lpRect->top;
if ( iX < rcWA.left + DETASTEP && iX!=rcWA.left )
{
//調整左
pWnd->SetWindowPos(NULL,rcWA.left,iY,0,0,SWP_NOSIZE);
lpRect->OffsetRect(rcWA.left-iX,0);
AdjustPos(lpRect);
return TRUE;
}
if ( iY < rcWA.top + DETASTEP && iY!=rcWA.top )
{
//調整上
pWnd->SetWindowPos(NULL ,iX,rcWA.top,0,0,SWP_NOSIZE);
lpRect->OffsetRect(0,rcWA.top-iY);
AdjustPos(lpRect);
return TRUE;
}
if ( iX + lpRect->Width() > rcWA.right - DETASTEP && iX !=rcWA.right-lpRect->Width() )
{
//調整右
pWnd->SetWindowPos(NULL ,rcWA.right-rcW.Width(),iY,0,0,SWP_NOSIZE);
lpRect->OffsetRect(rcWA.right-lpRect->right,0);
AdjustPos(lpRect);
return TRUE;
}
if ( iY + lpRect->Height() > rcWA.bottom - DETASTEP && iY !=rcWA.bottom-lpRect->Height() )
{
//調整下
pWnd->SetWindowPos(NULL ,iX,rcWA.bottom-rcW.Height(),0,0,SWP_NOSIZE);
lpRect->OffsetRect(0,rcWA.bottom-lpRect->bottom);
return TRUE;
}
return FALSE;
}
//然後在ONMOVEING事件中使用如下過程調用
CRect r=*pRect;
AdjustPos(this, &r);
*pRect=(RECT)r;
17.單擊視窗任意位置都可拖動視窗
方法一:
添加 WM_LBUTTONDOWN 的消息映射
void CTest6Dlg::OnLButtonDown(UINT nFlags, CPoint point)
{
PostMessage(WM_NCLBUTTONDOWN, HTCAPTION, 0);
CDialog::OnLButtonDown(nFlags, point);
}
方法二:
添加 WM_NCHITTEST 的消息映射
注意:在classwizard->message中找不到WM_NCHITTEST的,需要在頁籤class info->message filter中選擇window後該消息才會出現在message中。
void CTest6Dlg::OnNCHitTest(CPoint point)
{
return HTCAPTION;
// return CDialog::OnNCHitTest(point);
}
或者參考
http://msdn.microsoft.com/msdnmag/issues/02/12/CQA/default.aspx
18.用Enter鍵替換Tab鍵實作焦點切換
BOOL CTest6Dlg::PreTranslateMessage(MSG* pMsg)
{
if ( pMsg->message == WM_KEYDOWN )
{
if ( pMsg->wParam == VK_RETURN )
pMsg->wParam = VK_TAB;
}
return CDialog::PreTranslateMessage(pMsg);
}
19.在對話框添加快捷鍵
(1) 在CXXXApp中類中添加聲明
HACCEL m_haccel;
(2) 在resource view中右鍵點選樹的根目錄,選擇insert,添加一個新的Accelerator,預設ID為IDR_ACCELERATOR1。
在其中添加相應菜單的快捷鍵。
(3) 在BOOL CXXXApp::InitInstance()中添加代碼
m_haccel = LoadAccelerators(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_ACCELERATOR1));
(4) 添加CXXXApp類的 ProcessMessageFilter 消息映射函數
BOOL CTest6App::ProcessMessageFilter(int code, LPMSG lpMsg)
{
if ( m_haccel )
{
if ( ::TranslateAccelerator(m_pMainWnd->m_hWnd, m_haccel, lpMsg) )
return TRUE;
}
return CWinApp::ProcessMessageFilter(code, lpMsg);
}
或者參考
Q100770:
How to use accelerator keys and a main menu on the dialog box in Visual C++
http://support.microsoft.com/kb/100770/en-us
Adding Hot Keys to your Application
http://msdn.microsoft.com/msdnmag/issues/1200/c/default.aspx
20.對話框全屏
int cx, cy;
HDC dc = ::GetDC(NULL);
cx = GetDeviceCaps(dc,HORZRES) + GetSystemMetrics(SM_CXBORDER);
cy = GetDeviceCaps(dc,VERTRES) + GetSystemMetrics(SM_CYBORDER);
::ReleaseDC(0,dc);
// Remove caption and border
SetWindowLong(m_hWnd, GWL_STYLE,
GetWindowLong(m_hWnd, GWL_STYLE) & (~(WS_CAPTION | WS_BORDER)));
// Put window on top and expand it to fill screen
::SetWindowPos(m_hWnd, HWND_TOPMOST,
-(GetSystemMetrics(SM_CXBORDER)+1),
-(GetSystemMetrics(SM_CYBORDER)+1),
cx+1,cy+1, SWP_NOZORDER);
或參考
http://www.codeguru.com/cpp/w-d/dislog/dialog-basedapplications/article.php/c1837/
21.控制對話框最大最小尺寸
(1) 對話框的屬性的必須是resizing的
(2) 打開classwizard->class info标簽頁->message filter中選擇window
(3) 添加 WM_GETMINMAXINFO 消息映射
void CTest6Dlg::OnGetMinMaxInfo(MINMAXINFO *lpMMI)
{
lpMMI->ptMinTrackSize = CPoint(200, 200);
}
22. 建立無模式對話框
Q103788:
Creating a Modeless Dialog Box with MFC Libraries
http://support.microsoft.com/kb/103788/EN-US/
Visual C++ MFC Samples
MODELESS Sample: Uses a CDialog Object as a Modeless Dialog Box
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcsample/html/_sample_mfc_MODELESS.asp
23.在對話框中改變菜單項狀态(enable/disable, check/uncheck, change text)
Q242577:
You cannot change the state of a menu item from its command user-interface handler if the menu is attached to a dialog box in Visual C++
http://support.microsoft.com/kb/242577/en-us
24. 按下F1出現幫助
Q141724:
Context-Sensitive Help in a CDialog Object
http://support.microsoft.com/kb/141724/en-us
msdn中的介紹
http://msdn2.microsoft.com/en-us/library/dyd1yfww.aspx
或者如果你要屏蔽按下F1後出現的“找不到*.hlp檔案”的提示對話框
添加 WM_HELPINFO 消息映射
BOOL CTest6Dlg::OnHelpInfo(HELPINFO* pHelpInfo)
{
return TRUE;
//return CDialog::OnHelpInfo(pHelpInfo);//屏蔽該句
}
25. 對話框初始化設定輸入焦點的問題
預設情況下,對話框初始化顯示的焦點按照在對話框編輯期間設定的tab order的第一個控件來設定的。(設定tab order可在對話框的resource view中用Ctrl+D顯示出來,點滑鼠進行順序設定)。如果想人為的改變初始化時的輸入焦點,可在對話框的OnInitDialog中把return TRUE; 改為 return FALSE;
MSDN上的解釋如下:
Return Value
Specifies whether the application has set the input focus to one of the controls in the dialog box. If OnInitDialog returns nonzero, Windows sets the input focus to the first control in the dialog box. The application can return 0 only if it has explicitly set the input focus to one of the controls in the dialog box.
26. 在對話框間傳遞資料
CDlg1::OnButton1()
{
CDlg2 dlg2;
dlg2.m_str = _T("你好"; )
dlg2.m_bJudge = TRUE;
dlg2.DoModal();
}
//Dlg2.h
public:
CString m_str;
BOOL m_bJudge;
//Dlg2.cpp
CDlg2::OnInitDialog()
{
if (m_bJudge)
GetDlgItem(IDC_EDIT1)->SetWindowText(m_str);
}
27. 在 dlg1 中打開 dlg2 時,dlg2 能修改 dlg1 中的成員變量
//dlg1.cpp
#include "dlg2.h"
CDlg1::OnButton1()
{
CDlg2 dlg2;
dlg2.m_pDlg1 = this;
dlg2.DoModal();
}
//dlg2.h
class CDlg1;//添加dlg1類的聲明
class CDlg2 : public CDialog
{
...
public:
CDlg1 *m_pDlg1;
}
//dlg2.cpp
#include "dlg1.h"
至此,你可以在dlg2.cpp中通過m_pDlg1操作CDlg1類中的成員變量了。
28. 改變對話框字型,對話框大小改變的問題
Q145994:
How to calculate dialog box units based on the current font in Visual C++
http://support.microsoft.com/kb/q145994/
Q125681:
How To Calculate Dialog Base Units with Non-System-Based Font
http://support.microsoft.com/kb/125681/en-us
29. 進行大資料量計算的時候,導緻界面挂起無響應的問題
當在程式中需要進行大資料量計算的時候(比如搜尋磁盤,大資料量傳輸等),由于這些計算過程是在界面線程(UI Process)中,由此引發了界面線程的消息阻塞。我們建立一個工作線程(worker thread)來處理計算過程,以解決該問題。
下面是一個簡單的建立一個工作線程的實作:
//xxxdlg.h
static UINT MyThread(LPVOID pParam);
CWinThread* pMyThread;
//xxxdlg.cpp
CXXXDlg::OnButton1()
{
pMyThread = AfxBeginThread(MyThread, this);
pMyThread = NULL;
}
UINT CXXXDlg::MyThread(LPVOID pParam)
{
CXXXDlg *pDlg = (CXXXDlg *)pParam;
//這裡添加計算過程
return 0;
}