zoukankan      html  css  js  c++  java
  • 积累的VC编程小技巧之工具提示

    1.用鼠标移动基于对话框的无标题栏程序的简单方法

    void CVCTestDlg::OnLButtonDown(UINT nFlags, CPoint point) 
    {
        //一句话解决问题 
        SendMessage(WM_SYSCOMMAND,0xF012,0);
        CDialog::OnLButtonDown(nFlags, point);
    }

    2.对话框消息映射

    有对话框A,B
    从A中发消息给B然后B处理。
    准备工作,先定义消息,如下
    #define WM_B_NOTIFY WM_USER + 300 

    首先,必须将B的对话框句柄传送给A,暂时叫m_hWndB;

    在A的发送消息的地方这样写:
    ::SendMessage( m_hWndB,WM_B_NOTIFY,TRUE,NULL );

    这样A中的处理就完了,下面说B 中的
    首先定义消息处理函数,如下
    void B::ModiNotify( WPARAM wParam, LPARAM lParam )
    {
        MessageBox("小样,我就不信,搞不定你!");
    }

    然后加消息隐射,如下:
    BEGIN_MESSAGE_MAP(CB, CDialog)
        //{{AFX_MSG_MAP(CRPServerDlg)

        ON_MESSAGE( WM_B_NOTIFY,ModiNotify )

        //}}AFX_MSG_MAP
    END_MESSAGE_MAP()

    3.如何改变框对话或窗体视窗的背景颜色

    调用CWinApp : : SetDialogBkColor可以改变所有应用程序的背景颜色。第一个参数指定了背景颜色,第二个参数指定了文本颜色。下例将应用程序对话设置为蓝色背景和黄色文本。
    BOOL CSampleApp : : InitInstance ( )
    {

    //use blue dialog with yellow text .
    SetDialogBkColor (RGB (0, 0, 255 ), RGB ( 255 , 255 , 0 ) ) ;

    }
    需要重画对话(或对话的子控件)时,Windows向对话发送消息WM_CTLCOLOR,通常用户可以让Windows选择绘画背景的刷子,也可重置该消息指定刷子。下例说明了创建一个红色背景对话的步骤。
    首先,给对话基类增加一人成员变量CBursh :
    class CMyFormView : public CFormView
    {

    private :
    CBrush m_ brush ; // background brush

    } ;
    其次, 在类的构造函数中将刷子初始化为所需要的背景颜色。
    CMyFormView : : CMyFormView ( )
    {
    // Initialize background brush .
    m_brush .CreateSolidBrush (RGB ( 0, 0, 255 ) )
    }
    最后,使用ClassWizard处理WM_CTLCOLOR消息并返回一个用来绘画对话背景的刷子句柄。注意:由于当重画对话控件时也要调用该函数,所以要检测nCtlColor参量。
    HBRUSH CMyFormView : : OnCtlColor (CDC* pDC , CWnd*pWnd , UINT nCtlColor )
    {
    // Determine if drawing a dialog box . If we are , return +handle to
    //our own background brush . Otherwise let windows handle it .
    if (nCtlColor = = CTLCOLOR _ DLG )
    return (HBRUSH) m_brush .GetSafeHandle ( ) ;
    return CFormView : : OnCtlColor (pDC, pWnd , nCtlColor );
    }

    4.如何实现点一下对话框外面的区域,自动隐藏对话框?

      [问题提出]
        如果想在点击对话框外面的地方使得对话框关闭,该如何做?

      [解决方法]
        试试下面的代码,原理是在激活对话框时,捕获鼠标的动作,当鼠标点击时判断是否点击在对话框外,是的话就释放对话框.

      [程序实现]
        建立名为My的对话框程序.实现如下步骤:
        在MyDlg.h中加入:

        class CShowWindow1Dlg : public CDialog
        {
         // Construction
         public:
             int m_cx;
             int m_cy;
             ......
        };

        在MyDlg.cpp中:

        //定义消息映象,处理鼠标单击及激活
        BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
            //{{AFX_MSG_MAP(CMyDlg)
            ON_WM_LBUTTONDOWN()
            ON_WM_ACTIVATE()
            //}}AFX_MSG_MAP
        END_MESSAGE_MAP()

        void CMyDlg::OnLButtonDown(UINT nFlags, CPoint point)
        {
            CRect rect;
            GetClientRect(&rect);
            rect.InflateRect(m_cx, m_cy);
      
            //Release dialog if the user click outside it.
            if(!rect.PtInRect(point))
            {
               EndDialog(IDCANCEL);
            }

            CDialog::OnLButtonDown(nFlags, point);
        }

        void CMyDlg::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
        {
            CDialog::OnActivate(nState, pWndOther, bMinimized);

            if( nState == WA_ACTIVE || nState == WA_CLICKACTIVE)
                SetCapture();
            else
                ReleaseCapture();
        }

        BOOL CMyDlg::OnInitDialog()
        {
            CDialog::OnInitDialog();
            .....
            
            OSVERSIONINFO info;
            memset((char*)&info, 0, sizeof(OSVERSIONINFO));
            info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
            if(GetVersionEx(&info))
            {  //we don't run on Win32s, so check only two values
               if(info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
               {  //On windows 95
                  m_cx = GetSystemMetrics(SM_CXFIXEDFRAME);
                  m_cy = GetSystemMetrics(SM_CYFIXEDFRAME);
               }
               else
               {  //On NT
                  m_cx = GetSystemMetrics(SM_CXDLGFRAME);
                  m_cy = GetSystemMetrics(SM_CYDLGFRAME);
               }
            }
        }

         说明:
         1)WM_ACTIVATE消息在ClassWizard中没有,按如下步骤添加,右击CMyDlg类,选Add Windows Message Handle,接着在Filter for messages available to中选Window,在New Windows messages/events列表中就会出现WM_ACTIVATE,选中,点击Add Handler
         2)SM_CXDLGFRAME,SM_CYDLGFRAME   NT中取得有WS_DLGFRAMEstyle风格的窗口的高和宽 95中已经废弃而采用SM_CX_FIXEDFRAME和SM_CYFIXEDFRAME

    5.如何使FormView中显示dialog时,不是凹的

      [问题提出]
      为什么FormView中显示dialog时,是凹的,能不能不这样
      [解决方法]
      在Dialog的属性中:
        增加属性WS_BORDER   或者 WS_EX_WINDOWEDGE
      用程序实现:
      pView->ModifyStyle(,WS_BORDER) 或者pView->ModifyStyleEx(,WS_EX_WINDOWEDGE )

     

    6.对话框上建立View的方法

    OnInitDialog()
    {
      CDialog:;OnInitDialog();

    CRect rectWindows;
    GetWinodwRect(&rectWindows);
    CRuntimeClass *pViewClass=RUNTIME_CLASS(CXXXView);
    CCreateContext *pContext=new CCreateContext;
    pContext->m_pCurrentDoc=NULL;
    pContext->m_pCurrentFrame=NULL;
    pContext->m_pLastView=NULL;
    pContext->m_pNewDocTemplate=NULL;
    pContext->m_pNewViewClass=pViewClass;

    CWnd *pWnd=DYNAMIC_DOWNCAST(CWnd,pviewClass->CreateObject());
    pWnd->Create(NULL,NULL,AFX_WS_DEFAULT_VIEW,CRect(0,0,0,0),this,pContext);
    delete pContext;
    CXXXView *pView=DYUNAMIC_DOWNCAST(CXXXView,pWnd);
    ...............
    }

    7.模态对话框初始显示位置的控制

    正确的方法是在OnInitDialog中添加MoveWindow,如: 
         MoveWindow(0, 1, 300, 200); 
        需要注意的是前两个参数不能都为0。如果你确实希望把窗口放在(0, 0)处,可以在对话框设计窗口的属性中选中Absolute Align,然后再加入 
         MoveWindow(0, 0, 300, 200); 
        为什么会是这样?你看了MFC的源程序就会明白。原来MFC在调用你的OnInitDialog之后,会调用CDialog::CheckAutoCenter()(在dlgcore.cpp中)检查是否需要将窗口居中,你看了这个函数后就明白为什么需要上面那么做了。

     

    8.动态修改对话框的大小

      [问题提出]
        关于如何动态改变对话框的大小,我做了个Demo,大家看看.

      [程序实现]
         //本函数使用方法: 
         //第一个参数:如果是TRUE表示显示扩展的对话框,如果是FALSE,表示缩小对话框。 
         //第二个参数:表示本对话框的HWND, 
         //第三个参数:表示缩小后大小的控件的ID
        void COptionDlg::ExpandBox(BOOL fExpand, HWND hwnd, int nIDDefaultBox)
        {
             CWnd *pWndBox=GetDlgItem(nIDDefaultBox);
             RECT rcDefaultBox,rcChild,rcIntersection,rcWnd;
             pWndBox->GetWindowRect(&rcDefaultBox);
             HWND hwndChild = ::GetTopWindow(hwnd);
             for (; hwndChild != NULL; hwndChild = ::GetNextWindow(hwndChild,GW_HWNDNEXT)) 
             {
                      ::GetWindowRect(hwndChild, &rcChild);
                      if (!IntersectRect(&rcIntersection, &rcChild, &rcDefaultBox))
                               ::EnableWindow(hwndChild, fExpand);
             }
             ::GetWindowRect(hwnd, &rcWnd);
             if (GetWindowLong(hwnd, GWL_USERDATA) == 0)
             {
                      SetWindowLong(hwnd, GWL_USERDATA,
                               MAKELONG(rcWnd.right - rcWnd.left, 
                               rcWnd.bottom - rcWnd.top));
                      ::ShowWindow(pWndBox->m_hWnd, SW_HIDE);
             }
             ::SetWindowPos(hwnd, NULL, 0, 0,
                      rcDefaultBox.right - rcWnd.left,
                      rcDefaultBox.bottom - rcWnd.top,
                      SWP_NOZORDER | SWP_NOMOVE);
             if(fExpand)
             {
                      DWORD dwDims = GetWindowLong(hwnd, GWL_USERDATA);
                      ::SetWindowPos(hwnd, NULL, 0, 0,
                               LOWORD(dwDims), HIWORD(dwDims), SWP_NOZORDER | SWP_NOMOVE);
                      ::SendMessage(hwnd, DM_REPOSITION, 0, 0);
             }
        }

     

    9.隐藏对话框窗口(窗口没有焦点时)

    在程序启动时InitDialog中使用SetWindowPos将窗体设置到屏幕以外
    然后再隐藏
    1.OnInitDialog()函数里设置定时器:(WINDOWS   API里面响应消息WM_INITDIALOG   
      SetTimer(1,   1,   NULL);   
      2.
    添加处理WM_TIMER的消息处理函数OnTimer,添加代码:    
      if(nIDEvent   ==   1)    
      {   
          DeleteTimer(1);   
          ShowWindow(SW_HIDE);    
      } 

     

    10.如何实现点击对话框外的地方使对话框到主窗口的后面

    将桌面做为父窗口
    pMDlg = new CMDlg;
    pMDlg->Create(IDD_M_DIALOG,CWnd::GetDesktopWindow()/* 
    设置父窗口 */);
    pMDlg->ShowWindow(SW_SHOW); 
    然后在任务栏里隐藏对话框程序
    如何让对话框应用程序在在任务栏上不出现,并且不隐藏窗口。
    [解决方法]
       
    把对话框的扩展属性修改成为WS_EX_TOOLWINDOW
    [程序实现]
       
    把对话框的属性设置成为toolwindow,然后在需要的地方执行本代码。
       DWORD Style = ::GetWindowLong(AfxGetMainWnd()->m_hWnd,GWL_EXSTYLE);
       Style = WS_EX_TOOLWINDOW ;
       AfxGetMainWnd()->ShowWindow(FALSE);
       ::SetWindowLong(AfxGetMainWnd()->m_hWnd,GWL_EXSTYLE,Style); 
       AfxGetMainWnd()->ShowWindow(TRUE);

     

    11.怎么让无模式对话框显示在主窗口后面

    要解决这个问题的关键在于CDialog的Create并不能建立一个无属主的窗口.必须用另外方式建窗口.   
        
      比如你的对话框类叫CDlgNoOwner,在CMainFrame中加一个CDlgNoOwner类的成员变量,   
      弹出这个对话框的消息处理函数为   
        
      void   CMainFrame::OnNoowner()     
      {  

    CDlgNoOwner   *m_dlgTest=new   CDlgNoOwner(this);  
          HWND   hwndDlg=::CreateDialog( AfxGetInstanceHandle(),MAKEINTRESOURCE(                              CDlgNoOwner::IDD),NULL/*owner*/,NULL/*dlgproc*/);
          //
    注意此处DLGPROCNULL,并不要紧,因为接下要subclass   
          m_dlgTest->SubclassWindow   (hwndDlg);//
    挂接到成员变量!   
          m_dlgTest->ShowWindow   (SW_SHOW);   
          //
    这时可以看到一个"自由"的对话框弹出,和你的主窗口是平起平坐的.   
      }   
        
      
    当然不要忘了在对话框关闭时DestroyWindow()..那都是在对话框类中的标准处理了.

     

    12.如何得到屏幕的真实尺寸(以对话框为例)

    [问题提出]
    我的屏幕是1024*800,如何得到屏幕的真实大小,我用GetSystemMetrics(SM_CYFULLSCREEN)得到的高度总是小于800
    [问题解答]
    GetSystemMetrics(SM_CYFULLSCREEN)得到的只是屏幕用户区的大小。要得到屏幕的真实大小需要使用
    GetDeviceCaps函数,该API函数原型是这样的:

    int GetDeviceCaps(
      HDC hdc,     // handle to DC
      int nIndex   // index of capability
    );
    ///得到屏幕尺寸的代码如下
    void CMyDlg::OnPaint() 
    {
       CPaintDC dc(this); 
       int cx = ::GetDeviceCaps(dc.m_hDC,HORZRES);///得到宽度
       int cy = ::GetDeviceCaps(dc.m_hDC,VERTRES);///得到高度
       CDialog::OnPaint();

    }

     

    13.如何在对话框中加入工具条

       OnInitDialog 中加入下面代码:

      BOOL CYourDlg::OnInitDialog()

      {

           CDialog::OnInitDialog();  

           // Create the toolbar. To understand the meaning of the styles used, you

           // can take a look at the MSDN for the Create function of the CToolBar class.

           ToolBar.Create(this, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_TOOLTIPS |CBRS_FLYBY | CBRS_BORDER_BOTTOM);

          // I have assumed that you have named your toolbar's resource as IDR_TOOLBAR1.

          // If you have given it a different name, change the line below to accomodate

          // that by changing the parameter for the LoadToolBar function.

          ToolBar.LoadToolBar(IDR_TOOLBAR1);

          CRect rcClientStart;

          CRect rcClientNow;

          GetClientRect(rcClientStart);

          // To reposition and resize the control bar

          RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST,0, reposQuery, rcClientNow);

         CPoint ptOffset(rcClientNow.left - rcClientStart.left,rcClientNow.top-rcClientStart.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);

         rcWindow.right += rcClientStart.Width() - rcClientNow.Width();

         rcWindow.bottom += rcClientStart.Height() - rcClientNow.Height();

         MoveWindow(rcWindow, FALSE);

         // And position the control bars

         RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0);

         return TRUE;  // return TRUE  unless you set the focus to a control

      }

     

    14.如何改变对话框的形状

    可用下面一些涵数:

     CreatePolygonRgn
         CreateRectRgn
         CreateRoundRectRgn 
    .

      CRgn m_rgn;  // Put this in your dialog's header file. i.e. a member variable
     
      // This Gets the size of the Dialog: This piece of code is to be placed in the
      // OnInitDialog Function of your dialog.
     
      CRect rcDialog
      GetClientRect(rcDialog);
     
      // The following code Creates the area and assigns it to your Dialog
      m_rgn.CreateEllipticRgn(0, 0, rcDialog.Width(), rcDialogHeight());
      SetWindowRgn(GetSafeHwnd(), (HRGN) m_rgn, TRUE);

     

    15.如何在对话框中加入状态条

         定义 CStatusBar 变量:

      CStatusBar m_StatusBar;

         定义状态条指定状态:

      static UINT BASED_CODE indicators[] =

      {

         ID_INDICATOR_CAPS,

         ID_INDICATOR_NUM

      };

         在 OnInitDialog 中加入下面代码:

      m_StatusBar.CreateEx(this,SBT_TOOLTIPS,WS_CHILD|WS_VISIBLE|CBRS_BOTTOM,AFX_IDW_STATUS_BAR);

      // Set the indicators namely caps and nums lock status

      m_StatusBar.SetIndicators(indicators,sizeof(indicators)/sizeof(UINT));

      CRect rect;

      GetClientRect(&rect);

                 

      m_StatusBar.SetPaneInfo(0,ID_INDICATOR_CAPS,SBPS_NORMAL,rect.Width()/2);

      m_StatusBar.SetPaneInfo(1,ID_INDICATOR_NUM,SBPS_STRETCH ,rect.Width()/2);

      RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,ID_INDICATOR_NUM);

      m_StatusBar.GetStatusBarCtrl().SetBkColor(RGB(180,180,180));

     

    16.如何实现非客户区移动

    可用下面二种方法:

      // Handler for WM_LBUTTONDOWN message

      void CYourDialog::OnLButtonDown(UINT nFlags, CPoint point)

      {

         CDialog::OnLButtonDown(nFlags, point);

         PostMessage( WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM( point.x, point.y));

      }

      // Handler for WM_NCHITTEST message

      LONG CYourDialog::OnNcHitTest( UINT uParam, LONG lParam )

      { 

         int xPos = LOWORD(lParam);

         int yPos = HIWORD(lParam);

         UINT nHitTest = CDialog::OnNcHitTest(CSize(xPos, yPos));

         return (nHitTest == HTCLIENT) ? HTCAPTION : nHitTest;

      }

     

    17.如何使对话框初始为最小化状态

    在 OnInitDialog 中加入下面代码:

    SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, NULL);

     

    18.如何限定对话框大小范围

    在 WM_SIZING中加入下面代码:

       void CYourDialog::OnSizing(UINT fwSide, LPRECT pRect)

      {

         if(pRect->right - pRect->left <=200)

           pRect->right = pRect->left + 200;

          

         if(pRect->bottom - pRect->top <=200)

           pRect->bottom = pRect->top + 200;

         CDialog::OnSizing(fwSide, pRect);

      }

  • 相关阅读:
    权限控制
    包(package)
    this和super关键字
    成员变量的隐藏和方法重写(覆盖)
    转--htaccess语法教程 apache服务器伪静态规则教程
    转---高并发Web服务的演变——节约系统内存和CPU
    MYSQL 分表实践
    MySql主从配置实践及其优势浅谈
    一位IT牛人的十年经验之谈
    最近对Memcache的一些学习
  • 原文地址:https://www.cnblogs.com/lidabo/p/3703506.html
Copyright © 2011-2022 走看看