窗口应用技巧(
1
)
1 . 在任务栏隐藏对话框
ModifyStyleEx ( WS_EX_APPWINDOW , WS_EX_TOOLWINDOW );
=======================================================================================
2 . 使对话框为顶层窗口
SetWindowPos (& this -> wndTopMost , 0 , 0 , 0 , 0 , SWP_NOMOVE | SWP_NOSIZE );
=======================================================================================
3 . 在运行时添加最大化,最小化按钮
SetWindowLong ( this -> m_hWnd , GWL_STYLE ,
GetWindowLong ( this -> m_hWnd , GWL_STYLE ) |
WS_MINIMIZEBOX | WS_MAXIMIZEBOX );
UpdateWindow ();
=======================================================================================
4 . 使能对话框右上角关闭按钮
在 OnInitDialog 中
方法一:
CMenu * menu = GetSystemMenu ( FALSE );
menu -> ModifyMenu ( SC_CLOSE , MF_BYCOMMAND | MF_GRAYED );
方法二:
CMenu * menu = GetSystemMenu ( FALSE );
menu -> EnableMenuItem ( SC_CLOSE , MF_BYCOMMAND | MF_GRAYED );
=======================================================================================
5 . 当对话框一部分在屏幕外时,显示全部对话框
SendMessage ( DM_REPOSITION );
=======================================================================================
6 . 改变鼠标外形
添加 WM_SETCURSOR 消息映射函数
BOOL CTest6Dlg :: OnSetCursor ( CWnd * pWnd , UINT nHitTest , UINT message )
{
SetCursor ( AfxGetApp ()-> LoadStandardCursor ( IDC_HELP ));
return 0 ;
}
=======================================================================================
7 . 改变对话框背景色和文本颜色
在 CTest6App 的 InitInstance 中添加
SetDialogBkColor ( RGB ( 255 , 0 , 0 ), RGB ( 0 , 255 , 0 ));
=======================================================================================
8 . 改变对话框 caption 上的图标
导入自己的图标资源到工程中,把原来 ID 为 IDR_MAINFRAME 的资源删除,把新的图标的 ID 命名为
IDR_MAINFRAME
=======================================================================================
9 . 在主对话框显示前,显示一个 login 对话框
BOOL CTest6App :: InitInstance ()
{
//...
int nResponse ;
CLoginDlg loginDlg ;
nResponse = loginDlg . DoModal ();
if ( nResponse == IDOK )
{
}
if ( nResponse == IDCANCEL )
{
return FALSE ;
}
CTest6Dlg dlg ;
m_pMainWnd = & dlg ;
int nResponse = dlg . DoModal ();
if ( nResponse == IDOK )
{
}
else if ( nResponse == IDCANCEL )
{
}
return FALSE ;
}
然后重载 CLoginDlg 对话框的哦 OnOK (),在其中判断条件
void CLoginDlg :: OnOK ()
{
if (条件满足)
CDialog :: OnOK ();
else
AfxMessageBox ( _T ( "invalid password!" ));
}
=======================================================================================
10 . 在对话框中添加工具栏
方法一:添加以下代码到 OnInitDialog 中
if ( ! m_wndToolBar . Create ( this ) || ! m_wndToolBar . LoadToolBar ( IDR_TOOLBAR1 ) )
{
TRACE0 ( "Failed to Create Dialog Toolbar/n" );
EndDialog ( IDCANCEL );
}
CRect rcClientOld ; // 久客户区RECT
CRect rcClientNew ; // 加入TOOLBAR后的CLIENT RECT
GetClientRect ( rcClientOld ); //
// Called to reposition and resize control bars in the client area of a window
// The reposQuery FLAG does not really traw the Toolbar. It only does the calculations.
// And puts the new ClientRect values in rcClientNew so we can do the rest of the Math.
//重新计算RECT大小
RepositionBars ( AFX_IDW_CONTROLBAR_FIRST ,
AFX_IDW_CONTROLBAR_LAST ,
0 ,
reposQuery ,
rcClientNew );
// All of the Child Windows (Controls) now need to be moved so the Tollbar does not cover
them up .
//所有的子窗口将被移动,以免被TOOLBAR覆盖
// Offest to move all child controls after adding Tollbar
//计算移动的距离
CPoint ptOffset ( rcClientNew . left - rcClientOld . left ,
rcClientNew . top - rcClientOld . top );
CRect rcChild ;
CWnd * pwndChild = GetWindow ( GW_CHILD ); //得到子窗口
while ( pwndChild ) // 处理所有子窗口
{
//移动所有子窗口
pwndChild -> GetWindowRect ( rcChild );
ScreenToClient ( rcChild );
rcChild . OffsetRect ( ptOffset );
pwndChild -> MoveWindow ( rcChild , FALSE );
pwndChild = pwndChild -> GetNextWindow ();
}
CRect rcWindow ;
GetWindowRect ( rcWindow ); // 得到对话框RECT
rcWindow . right += rcClientOld . Width () - rcClientNew . Width (); // 修改对话框尺寸
rcWindow . bottom += rcClientOld . Height () - rcClientNew . Height ();
MoveWindow ( rcWindow , FALSE ); // Redraw Window
RepositionBars ( AFX_IDW_CONTROLBAR_FIRST , AFX_IDW_CONTROLBAR_LAST , 0 );
方法二:
http : //www.codeproject.com/dialog/dlgtoolstatusbar.asp
=======================================================================================
11 .响应对话框的最大化、最小化、关闭、恢复事件
方法一:添加 WM_SYSCOMMAND 消息映射函数
void CTest6Dlg :: OnSysCommand ( UINT nID , LPARAM lParam )
{
if ( ( nID & 0xFFF0 ) == IDM_ABOUTBOX )
{
CAboutDlg dlgAbout ;
dlgAbout . DoModal ();
}
else
{
if ( nID == SC_MAXIMIZE )
{
AfxMessageBox ( _T ( "最大化" ));
}
else if ( nID == SC_MINIMIZE )
{
AfxMessageBox ( _T ( "最小化" ));
}
else if ( nID == SC_CLOSE )
{
AfxMessageBox ( _T ( "关闭" ));
}
CDialog :: OnSysCommand ( nID , lParam );
}
方法二:添加 WM_SIZE 消息映射函数
void CTest6Dlg :: OnSize ( UINT nType , int cx , int cy )
{
CDialog :: OnSize ( nType , cx , cy );
if ( nType == SIZE_MAXIMIZED )
{
AfxMessageBox ( _T ( "最大化" ));
}
else if ( nType == SIZE_MINIMIZED )
{
AfxMessageBox ( _T ( "最小化" ));
}
else if ( nType == SIZE_RESTORED )
{
AfxMessageBox ( _T ( "恢复" ));
}
}
=======================================================================================
12 .代码实现窗口最小化,最大化,关闭
PostMessage ( WM_SYSCOMMAND , SC_MINIMIZE );
PostMessage ( WM_SYSCOMMAND , SC_MAXIMIZE );
PostMessage ( WM_SYSCOMMAND , SC_CLOSE );
=======================================================================================
13 .按下 ESC 和 ENTER 键时禁止关闭对话框
方法一:
( 1 ) 重载 OnCancel 和 OnOk ,屏蔽其中的 CDialog :: OnCancel ()和 CDialog :: OnOk ();
( 2 ) 添加以下代码
void CTest6Dlg :: OnSysCommand ( UINT nID , LPARAM lParam )
{
if (( nID & 0xFFF0 ) == IDM_ABOUTBOX )
{
CAboutDlg dlgAbout ; //if you have an about dialog
dlgAbout . DoModal ();
}
else if (( nID & 0xFFF0 ) == SC_CLOSE )
{
//用户点击右上角"X"
EndDialog ( IDOK );
}
else
{
CDialog :: OnSysCommand ( nID , lParam );
}
}
方法二:
BOOL CTest6Dlg :: PreTranslateMessage ( MSG * pMsg )
{
if ( pMsg -> message == WM_KEYDOWN )
{
switch ( pMsg -> wParam )
{
case VK_ESCAPE :
return TRUE ; //直接返回TRUE
break ;
case VK_RETURN :
return TRUE ;
break ;
}
}
return CDialog :: PreTranslateMessage ( pMsg );
}
方法三:
Q122489 :
How to Disable Default Pushbutton Handling for MFC Dialog
http : //support.microsoft.com/kb/122489/en-us
=======================================================================================
14 .在对话框中处理键盘鼠标消息
处理 PreTranslateMessage 消息
以下代码示例只演示了键盘 WM_KEYDOWN 消息,你也可以处理鼠标消息,比如
WM_LBUTTONDOWN , WM_LBUTTONUP , WM_RBUTTONDOWN 等。
BOOL CTest6Dlg :: PreTranslateMessage ( MSG * pMsg )
{
/**********************************************************/
/* 当焦点在combobox(drop down风格)的edit上,响应回车 */
/***********************************************************/
if ( pMsg -> message == WM_KEYDOWN )
{
switch ( pMsg -> wParam )
{
case VK_RETURN :
CEdit * pEdit = ( CEdit *) m_combo1 . GetWindow ( GW_CHILD );
if ( pMsg -> hwnd == pEdit -> m_hWnd )
{
AfxMessageBox ( "在combobox的edit中按下了Enter!" );
}
return TRUE ;
}
}
/****************************************/
/* ALT为WM_SYSKEYDOWN */
/****************************************/
if ( pMsg -> message == WM_SYSKEYDOWN )
{
switch ( pMsg -> wParam )
{
case VK_F1 :
if (:: GetKeyState ( VK_MENU ) < 0 ) //ALT+F1
{
AfxMessageBox ( "按下了ALT+F1" );
return TRUE ;
}
}
}
/****************************************/
/* 在clistctrl中按ctrl+A选中所有项 */
/****************************************/
if ( pMsg -> message == WM_KEYDOWN )
{
if ( pMsg -> hwnd == GetDlgItem ( IDC_LIST1 )-> m_hWnd )
{
switch ( pMsg -> wParam )
{
case 65 : //A
if (:: GetKeyState ( VK_CONTROL ) < 0 ) //Shift+enter
{
for ( int i = 0 ; i< m_list . GetItemCount (); i ++)
{
m_list . SetItemState ( i , LVIS_SELECTED | LVIS_FOCUSED ,
LVIS_SELECTED | LVIS_FOCUSED );
}
}
return TRUE ;
}
}
}
/****************************************/
/* 当焦点在combobox,弹出自定义菜单 */
/****************************************/
if ( pMsg -> message == WM_RBUTTONDOWN )
{
CEdit * pEdit = ( CEdit *) m_combo1 . GetWindow ( GW_CHILD );
if ( pMsg -> hwnd == pEdit -> m_hWnd )
{
DWORD dwPos = GetMessagePos ();
CPoint point ( LOWORD ( dwPos ), HIWORD ( dwPos ) );
ScreenToClient (& point );
ClientToScreen (& point );
CMenu menu ;
VERIFY ( menu . LoadMenu ( IDR_MENU1 ) );
CMenu * popup = menu . GetSubMenu ( 0 );
ASSERT ( popup != NULL );
popup -> TrackPopupMenu ( TPM_LEFTALIGN | TPM_RIGHTBUTTON , point . x , point . y , this );
}
}
return CDialog :: PreTranslateMessage ( pMsg );
}
=======================================================================================
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 );
}
1 . 在任务栏隐藏对话框
ModifyStyleEx ( WS_EX_APPWINDOW , WS_EX_TOOLWINDOW );
=======================================================================================
2 . 使对话框为顶层窗口
SetWindowPos (& this -> wndTopMost , 0 , 0 , 0 , 0 , SWP_NOMOVE | SWP_NOSIZE );
=======================================================================================
3 . 在运行时添加最大化,最小化按钮
SetWindowLong ( this -> m_hWnd , GWL_STYLE ,
GetWindowLong ( this -> m_hWnd , GWL_STYLE ) |
WS_MINIMIZEBOX | WS_MAXIMIZEBOX );
UpdateWindow ();
=======================================================================================
4 . 使能对话框右上角关闭按钮
在 OnInitDialog 中
方法一:
CMenu * menu = GetSystemMenu ( FALSE );
menu -> ModifyMenu ( SC_CLOSE , MF_BYCOMMAND | MF_GRAYED );
方法二:
CMenu * menu = GetSystemMenu ( FALSE );
menu -> EnableMenuItem ( SC_CLOSE , MF_BYCOMMAND | MF_GRAYED );
=======================================================================================
5 . 当对话框一部分在屏幕外时,显示全部对话框
SendMessage ( DM_REPOSITION );
=======================================================================================
6 . 改变鼠标外形
添加 WM_SETCURSOR 消息映射函数
BOOL CTest6Dlg :: OnSetCursor ( CWnd * pWnd , UINT nHitTest , UINT message )
{
SetCursor ( AfxGetApp ()-> LoadStandardCursor ( IDC_HELP ));
return 0 ;
}
=======================================================================================
7 . 改变对话框背景色和文本颜色
在 CTest6App 的 InitInstance 中添加
SetDialogBkColor ( RGB ( 255 , 0 , 0 ), RGB ( 0 , 255 , 0 ));
=======================================================================================
8 . 改变对话框 caption 上的图标
导入自己的图标资源到工程中,把原来 ID 为 IDR_MAINFRAME 的资源删除,把新的图标的 ID 命名为
IDR_MAINFRAME
=======================================================================================
9 . 在主对话框显示前,显示一个 login 对话框
BOOL CTest6App :: InitInstance ()
{
//...
int nResponse ;
CLoginDlg loginDlg ;
nResponse = loginDlg . DoModal ();
if ( nResponse == IDOK )
{
}
if ( nResponse == IDCANCEL )
{
return FALSE ;
}
CTest6Dlg dlg ;
m_pMainWnd = & dlg ;
int nResponse = dlg . DoModal ();
if ( nResponse == IDOK )
{
}
else if ( nResponse == IDCANCEL )
{
}
return FALSE ;
}
然后重载 CLoginDlg 对话框的哦 OnOK (),在其中判断条件
void CLoginDlg :: OnOK ()
{
if (条件满足)
CDialog :: OnOK ();
else
AfxMessageBox ( _T ( "invalid password!" ));
}
=======================================================================================
10 . 在对话框中添加工具栏
方法一:添加以下代码到 OnInitDialog 中
if ( ! m_wndToolBar . Create ( this ) || ! m_wndToolBar . LoadToolBar ( IDR_TOOLBAR1 ) )
{
TRACE0 ( "Failed to Create Dialog Toolbar/n" );
EndDialog ( IDCANCEL );
}
CRect rcClientOld ; // 久客户区RECT
CRect rcClientNew ; // 加入TOOLBAR后的CLIENT RECT
GetClientRect ( rcClientOld ); //
// Called to reposition and resize control bars in the client area of a window
// The reposQuery FLAG does not really traw the Toolbar. It only does the calculations.
// And puts the new ClientRect values in rcClientNew so we can do the rest of the Math.
//重新计算RECT大小
RepositionBars ( AFX_IDW_CONTROLBAR_FIRST ,
AFX_IDW_CONTROLBAR_LAST ,
0 ,
reposQuery ,
rcClientNew );
// All of the Child Windows (Controls) now need to be moved so the Tollbar does not cover
them up .
//所有的子窗口将被移动,以免被TOOLBAR覆盖
// Offest to move all child controls after adding Tollbar
//计算移动的距离
CPoint ptOffset ( rcClientNew . left - rcClientOld . left ,
rcClientNew . top - rcClientOld . top );
CRect rcChild ;
CWnd * pwndChild = GetWindow ( GW_CHILD ); //得到子窗口
while ( pwndChild ) // 处理所有子窗口
{
//移动所有子窗口
pwndChild -> GetWindowRect ( rcChild );
ScreenToClient ( rcChild );
rcChild . OffsetRect ( ptOffset );
pwndChild -> MoveWindow ( rcChild , FALSE );
pwndChild = pwndChild -> GetNextWindow ();
}
CRect rcWindow ;
GetWindowRect ( rcWindow ); // 得到对话框RECT
rcWindow . right += rcClientOld . Width () - rcClientNew . Width (); // 修改对话框尺寸
rcWindow . bottom += rcClientOld . Height () - rcClientNew . Height ();
MoveWindow ( rcWindow , FALSE ); // Redraw Window
RepositionBars ( AFX_IDW_CONTROLBAR_FIRST , AFX_IDW_CONTROLBAR_LAST , 0 );
方法二:
http : //www.codeproject.com/dialog/dlgtoolstatusbar.asp
=======================================================================================
11 .响应对话框的最大化、最小化、关闭、恢复事件
方法一:添加 WM_SYSCOMMAND 消息映射函数
void CTest6Dlg :: OnSysCommand ( UINT nID , LPARAM lParam )
{
if ( ( nID & 0xFFF0 ) == IDM_ABOUTBOX )
{
CAboutDlg dlgAbout ;
dlgAbout . DoModal ();
}
else
{
if ( nID == SC_MAXIMIZE )
{
AfxMessageBox ( _T ( "最大化" ));
}
else if ( nID == SC_MINIMIZE )
{
AfxMessageBox ( _T ( "最小化" ));
}
else if ( nID == SC_CLOSE )
{
AfxMessageBox ( _T ( "关闭" ));
}
CDialog :: OnSysCommand ( nID , lParam );
}
方法二:添加 WM_SIZE 消息映射函数
void CTest6Dlg :: OnSize ( UINT nType , int cx , int cy )
{
CDialog :: OnSize ( nType , cx , cy );
if ( nType == SIZE_MAXIMIZED )
{
AfxMessageBox ( _T ( "最大化" ));
}
else if ( nType == SIZE_MINIMIZED )
{
AfxMessageBox ( _T ( "最小化" ));
}
else if ( nType == SIZE_RESTORED )
{
AfxMessageBox ( _T ( "恢复" ));
}
}
=======================================================================================
12 .代码实现窗口最小化,最大化,关闭
PostMessage ( WM_SYSCOMMAND , SC_MINIMIZE );
PostMessage ( WM_SYSCOMMAND , SC_MAXIMIZE );
PostMessage ( WM_SYSCOMMAND , SC_CLOSE );
=======================================================================================
13 .按下 ESC 和 ENTER 键时禁止关闭对话框
方法一:
( 1 ) 重载 OnCancel 和 OnOk ,屏蔽其中的 CDialog :: OnCancel ()和 CDialog :: OnOk ();
( 2 ) 添加以下代码
void CTest6Dlg :: OnSysCommand ( UINT nID , LPARAM lParam )
{
if (( nID & 0xFFF0 ) == IDM_ABOUTBOX )
{
CAboutDlg dlgAbout ; //if you have an about dialog
dlgAbout . DoModal ();
}
else if (( nID & 0xFFF0 ) == SC_CLOSE )
{
//用户点击右上角"X"
EndDialog ( IDOK );
}
else
{
CDialog :: OnSysCommand ( nID , lParam );
}
}
方法二:
BOOL CTest6Dlg :: PreTranslateMessage ( MSG * pMsg )
{
if ( pMsg -> message == WM_KEYDOWN )
{
switch ( pMsg -> wParam )
{
case VK_ESCAPE :
return TRUE ; //直接返回TRUE
break ;
case VK_RETURN :
return TRUE ;
break ;
}
}
return CDialog :: PreTranslateMessage ( pMsg );
}
方法三:
Q122489 :
How to Disable Default Pushbutton Handling for MFC Dialog
http : //support.microsoft.com/kb/122489/en-us
=======================================================================================
14 .在对话框中处理键盘鼠标消息
处理 PreTranslateMessage 消息
以下代码示例只演示了键盘 WM_KEYDOWN 消息,你也可以处理鼠标消息,比如
WM_LBUTTONDOWN , WM_LBUTTONUP , WM_RBUTTONDOWN 等。
BOOL CTest6Dlg :: PreTranslateMessage ( MSG * pMsg )
{
/**********************************************************/
/* 当焦点在combobox(drop down风格)的edit上,响应回车 */
/***********************************************************/
if ( pMsg -> message == WM_KEYDOWN )
{
switch ( pMsg -> wParam )
{
case VK_RETURN :
CEdit * pEdit = ( CEdit *) m_combo1 . GetWindow ( GW_CHILD );
if ( pMsg -> hwnd == pEdit -> m_hWnd )
{
AfxMessageBox ( "在combobox的edit中按下了Enter!" );
}
return TRUE ;
}
}
/****************************************/
/* ALT为WM_SYSKEYDOWN */
/****************************************/
if ( pMsg -> message == WM_SYSKEYDOWN )
{
switch ( pMsg -> wParam )
{
case VK_F1 :
if (:: GetKeyState ( VK_MENU ) < 0 ) //ALT+F1
{
AfxMessageBox ( "按下了ALT+F1" );
return TRUE ;
}
}
}
/****************************************/
/* 在clistctrl中按ctrl+A选中所有项 */
/****************************************/
if ( pMsg -> message == WM_KEYDOWN )
{
if ( pMsg -> hwnd == GetDlgItem ( IDC_LIST1 )-> m_hWnd )
{
switch ( pMsg -> wParam )
{
case 65 : //A
if (:: GetKeyState ( VK_CONTROL ) < 0 ) //Shift+enter
{
for ( int i = 0 ; i< m_list . GetItemCount (); i ++)
{
m_list . SetItemState ( i , LVIS_SELECTED | LVIS_FOCUSED ,
LVIS_SELECTED | LVIS_FOCUSED );
}
}
return TRUE ;
}
}
}
/****************************************/
/* 当焦点在combobox,弹出自定义菜单 */
/****************************************/
if ( pMsg -> message == WM_RBUTTONDOWN )
{
CEdit * pEdit = ( CEdit *) m_combo1 . GetWindow ( GW_CHILD );
if ( pMsg -> hwnd == pEdit -> m_hWnd )
{
DWORD dwPos = GetMessagePos ();
CPoint point ( LOWORD ( dwPos ), HIWORD ( dwPos ) );
ScreenToClient (& point );
ClientToScreen (& point );
CMenu menu ;
VERIFY ( menu . LoadMenu ( IDR_MENU1 ) );
CMenu * popup = menu . GetSubMenu ( 0 );
ASSERT ( popup != NULL );
popup -> TrackPopupMenu ( TPM_LEFTALIGN | TPM_RIGHTBUTTON , point . x , point . y , this );
}
}
return CDialog :: PreTranslateMessage ( pMsg );
}
=======================================================================================
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 );
}