[转贴]窗口应用技巧(1)

窗口应用技巧( 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 );
     
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值