积累的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*/);
      //
注意此处 DLGPROC NULL, 并不要紧 , 因为接下要 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);

  }

你可能感兴趣的:(编程,windows,null,dialog,工具,construction)