VC编程常用捷径

来源:互联网 发布:剑三花哥捏脸数据 编辑:程序博客网 时间:2024/06/06 18:35

VC编程常用捷径     

1. 如何获取应用程序的 实例句柄?
      应用程序的 实例句柄保存在CWinAppIm_hInstance 中,可以这么调用
      AfxGetInstancdHandle获得句柄.
      Example: HANDLE hInstance=AfxGetInstanceHandle();

   2. 如何通过代码获得应用程序主窗口的 指针?
     主窗口的 指针保存在CWinThread::m_pMainWnd中,调用 AfxGetMainWnd实现。
      AfxGetMainWnd() ->ShowWindow(SW_SHOWMAXMIZED); //使程序最大化.

   3.如何在程序中获得其他程序的 图标?
      两种方法:
        (1) SDK函数 SHGetFileInfo 或使用 ExtractIcon获得图标资源的 handle,
        (2) SDK函数 SHGetFileInfo获得有关文件的 很多信息,如大小图标,属性,
           类型等.
          Example(1): 在程序窗口左上角显示 NotePad图标.

           void CSampleView: OnDraw(CDC * pDC)
             {
                if( :: SHGetFileInfo(_T("c:\\pwin95\\notepad.exe"),0,
                     &stFileInfo,sizeof(stFileInfo),SHGFI_ICON))
                   {
                     pDC ->DrawIcon(10,10,stFileInfo.hIcon);
                   }
              }

                                                                          
            Example(2):同样功能,Use ExtractIcon Function

            void CSampleView:: OnDraw(CDC *pDC)
              {
                HICON hIcon=:: ExtractIcon(AfxGetInstanceHandle(),_T
                 ("NotePad.exe"),0);

                if (hIcon &&hIcon!=(HICON)-1)
                   pDC->DrawIcon(10,10,hIcon);
                }
   说明: 获得notepad.exe的路径正规上来说用GetWindowsDirectory 函数得到,
      如果是调用 win95下的画笔,应该用访问注册表的方法获得其路径,要作成一个
     比较考究的程序,考虑应该全面点.

   4.如何编程结束应用程序?如何编程控制windows的重新引导?
      这是个很简单又是编程中经常要遇到的问题.
     第一问,向窗口发送 WM_CLOSE消息,调用 CWnd::OnClose成员函数.允许对用户提示
    是否保存修改过的数据.
     Example: AfxGetMainWindow()->SendMessage(WM_CLOSE);

    还可以创建一个自定义的函数 Terminate Window

      void Terminate Window(LPCSTR pCaption)
      {
          CWnd *pWnd=Cwnd::FindWindow(NULL,pCaption);
               if (pWnd)
                  pWnd ->SendMessage(WM_CLOSE);
      }

   说明: FindWindow函数不是提倡的做法,因为它无法处理标题栏自动改变,比如
   我们要检测 Notepad是不是已运行而事先不知道Notepad的标题栏,这时 FindWindow就
   无能为力了,可以通过枚举 windows任务列表的办法来实现。 在 机械出版社
   "Windows 95 API开发人员指南"一书有比较详细的介绍,这里就不再多说乐。

  第二问,Use ExitWindowsEx Function函数控制系统是重新引导,还是重启 windows.
   前面已经有人讲过乐,就不再提了。

   5.怎样加栽其他的应用程序?
    我记得这好象是出场频度很高的问题。
    三个SDK函数 winexec, shellexecute,createprocess可以使用。
     WinExec最简单,两个参数,前一个指定路径,后一个指定显示方式.后一个参数
  值得说一下,比如泥用 SW_SHOWMAXMIZED方式去加栽一个无最大化按钮的 程序,呵呵
  就是Neterm,calc等等,就不会出现正常的 窗体,但是已经被加到任务列表里了。

    
    ShellExecute较 WinExex灵活一点,可以指定工作目录,下面的 Example就是直接
  打开 c:\temp\1.txt,而不用加栽与 txt文件关联的应用程序,很多安装程序完成后
  都会打开一个窗口,来显示Readme or Faq,偶猜就是这么作的啦.
    ShellExecute(NULL,NULL,_T("1.txt"),NULL,_T("c:\\temp"),SW_SHOWMAXMIZED);

    CreateProcess最复杂,一共有十个参数,不过大部分都可以用NULL代替,它可以
    指定进程的安全属性,继承信息,类的优先级等等.来看个很简单的 Example:
       STARTUPINFO stinfo;   //启动窗口的信息
       PROCESSINFO procinfo;  //进程的信息

     CreateProcess(NULL,_T("notepad.exe"),NULL,NULL.FALSE, NORMAL_PRIORITY_
       CLASS,NULL,NULL, &stinfo,&procinfo);

    6. 确定应用程序的 路径
       前些天好象有人问过这个问题.
        Use GetModuleFileName 获得应用程序的路径,然后去掉可执行文件名。
          Example:
           TCHAR exeFullPath[MAX_PATH]; // MAX_PATH在API中定义了吧,好象是128
           GetModuleFileName(NULL,exeFullPath,MAX_PATH)

     7. 获得各种目录信息
        Windows目录: Use "GetWindowsDirectory“
        Windows下的system目录: Use "GetSystemDirectory"
        temp目录: Use "GetTempPath "
         当前目录: Use "GetCurrentDirectory"
       请注意前两个函数的第一个参数为 目录变量名,后一个为缓冲区; 后两个相反.

     8. 如何自定义消息
        也有人问过的,其实不难。
          (1) 手工定义消息,可以这么写 #define WM_MY_MESSAGE(WM_USER+100),
            MS 推荐的至少是 WM_USER+100;
          (2)写消息处理函数,用 WPARAM,LPARAM返回LRESULT.
             LRESULT CMainFrame::OnMyMessage(WPARAM wparam,LPARAM lParam)
              {

                //加入你的处理函数
              }
           (3)  在类的 AFX_MSG处进行声明,也就是常说的"宏映射"

 

9. 如何改变窗口的 图标?
    向窗口发送 WM_SECTION消息。
    Example:
      HICON hIcon=AfxGetApp() ->LoadIcon(IDI_ICON);
      ASSERT(hIcon);
      AfxGetMainWnd() ->SendMessage(WM_SECTION,TRUE,(LPARAM) hIcon);

10. 如何改变窗口的 缺省风格?
      重栽 CWnd:: PreCreateWindow 并修改CREATESTRUCT结构来指定窗口风格和其他
     创建信息.
     Example: Delete "Max" Button and Set Original Window's Position and Size

      BOOL CMainFrame::  PreCreateWindow (CREATESTRUCT &cs)
      {
       cs.style &=~WS_MAXINIZEMOX;
                                                                              
       cs.x=cs.y=0;
       cs.cx=GetSystemMetrics(SM_CXSCREEN/2);
       cs.cy=GetSystemMetrics(SM_CYSCREEN/2);

        return CMDIFramewnd ::PreCreateWindow(cs);

      }

  11.  如何将窗口居中显示?
        Easy, Call Function CWnd:: Center Windows

         Example(1):  Center Window( );  //Relative to it's parent
          // Relative to Screen
         Example(2):  Center Window(CWnd:: GetDesktopWindow( ));
          //Relative to Application's MainWindow
         AfxGetMainWnd( ) -> Center Window( );

   12. 如何让窗口和 MDI窗口一启动就最大化和最小化?
       先说窗口。
       在 InitStance 函数中设定 m_nCmdShow的 取值.
         m_nCmdShow=SW_SHOWMAXMIZED ;  //最大化
         m_nCmdShow=SW_SHOWMINMIZED ;  //最小化
         m_nCmdShow=SW_SHOWNORMAL   ;   //正常方式

        MDI窗口:
          如果是创建新的应用程序,可以用 MFC AppWizard 的Advanced 按钮并在
           MDI子窗口风格组中检测最大化或最小化; 还可以重载 MDI Window 的
            PreCreateWindow函数,设置WS_MAXMIZE or WS_MINMIZE;
         如果从 CMDIChildWnd 派生,调用 OnInitialUpdate函数中的 CWnd::Show
        Window来指定 MDI Child Window的 风格。

   13. 如何使程序保持极小状态?
       很有意思的 问题
        这么办: 在恢复程序窗体大小时, Windows会发送WM_QUERY-OPEN消息,
        用 ClassWizard设置成员函数 OnQueryOpen() ,add following code:
            Bool CMainFrame:: OnQueryOpen( )
              {
                 Return false;
              }

   14. 如何限制窗口的 大小?
      也就是 FixedDialog形式。  Windows 发送 WM_GETMAXMININFO消息来跟踪,
    响应它,在 OnGetMAXMININFO 中写代码:

   15.  如何使窗口不可见?
    很简单,用SW_HIDE 隐藏窗口,可以结合 FindWindow,ShowWindow 控制.

   16. 如何使窗口始终在最前方?
      两种途径.
       BringWindowToTop(Handle);
       SetWindowPos函数,指定窗口的 最顶风格,用WS_EX_TOPMOST扩展窗口的 风格

       Example:
         void  ToggleTopMost( CWnd *pWnd)
          {
             ASSERT_VALID(pWnd);
             pWnd ->SetWindowPos(pWnd-> GetStyle( ) &WS_EX_TOPMOST)?
              &wndNoTopMOST: &wndTopMost,0,0,0,0,SSP_NOSIZE|WSP_NOMOVE);
           }
17、如何创建一个字回绕的CEditView
    重载CWnd : : PreCreateWindow和修改CREATESTRUCT结构,关闭CEditView对象
的ES_AUTOHSCROLL和WS_HSCROLL风格位, 由于CEditView : : PreCreateWindow显示
设置cs. style,调用基类函数后要修改cs . style。
BOOL CSampleEDitView : : PreCreateWindow (CREATESTRUCT&cs)
{
    //First call basse class function .
    BOOL bResutl =CEditView : : PreCreateWindow (cs) ;

    // Now specify the new window style .
    cs.style &= ~ (ES_AUTOHSCROLL |WS_HSCROLL);
    return bResult ;
}

18、通用控件的显示窗口

    MFC提供了几个CView派生的视窗类, 封装了通用控件的功能,但仍然使用工
作框文档显示窗口体系结构:CEditView封装了编辑控件,CTreeView保持了树列表
控件,CListView封装了列表显示窗口控件,CRichEditView可以处理多种编辑控件。

19、移动窗口
    调用CWnd : : SetWindowPos并指定SWP_NOSIZE标志。目的位置与父窗口
有关(顶层窗口与屏幕有关)。调用CWnd : : MoveWindow时必须要指定窗口
的大小。
//Move window to positoin 100 , 100 of its parent window .
SetWindowPos (NULL, 100 , 100 , 0 , 0 , SWP_NOSIZE |SWP_NOAORDER);

20、重置窗口的大小

    调用CWnd: : SetWindowPos并指定SWP_NOMOVE标志, 也可调用
CWnd : : MoveWindow 但必须指定窗口的位置。
// Get the size of the window .
Crect reWindow ;
GetWindowRect (reWindow );

//Make the window twice as wide and twice as tall .
SetWindowPos (NULL , 0 , 0 , reWindow . Width ( ) *2,
              reWindow . Height () * 2,
     SWP_NOMOVE |SWP_NOZORDER );

1、如何创建一个不规则形状的窗口

   可以使用新的SDK函数SetWindowRgn。该函数将绘画和鼠标消息限定在窗口的一
个指定的区域,实际上使窗口成为指定的不规则形状。
    使用AppWizard创建一个基于对的应用程序并使用资源编辑器从主对话资源中删
除所在的缺省控件、标题以及边界。
    给对话类增加一个CRgn数据成员,以后要使用该数据成员建立窗口区域。
Class CRoundDlg : public CDialog
{
    …
private :
    Crgn m_rgn : // window region
    …
} ;
    修改OnInitDialog函数建立一个椭圆区域并调用SetWindowRgn将该区域分配给
窗口:
BOOL CRoundDlg : : OnInitDialog ( )
{
    CDialog : : OnInitDialog ( ) ;
    //Get size of dialog .
    CRect rcDialog ;
    GetClientRect (rcDialog );

    // Create region and assign to window .
    m_rgn . CreateEllipticRgn  (0 , 0 , rcDialog.Width ( ) , rcDialog .Height (
)
);

    return TRUE ;
}
    通过建立区域和调用SetWindowRgn,已经建立一个不规则形状的窗口,下面的例
子程序是修改OnPaint函数使窗口形状看起来象一个球形体。
voik CRoundDlg : : OnPaint ( )
{
    CPaintDC de (this) ; // device context for painting .
    //draw ellipse with out any border
    dc. SelecStockObject (NULL_PEN);

    //get the RGB colour components of the sphere color
    COLORREF color= RGB( 0 , 0 , 255);
    BYTE byRed =GetRValue (color);
    BYTE byGreen = GetGValue (color);
    BYTE byBlue = GetBValue (color);

    // get the size of the view window
    Crect rect ;
    GetClientRect  (rect);

    // get minimun number of units
    int nUnits =min (rect.right , rect.bottom );

    //calculate he horiaontal and vertical step size
    float fltStepHorz = (float) rect.right /nUnits ;
    float fltStepVert = (float) rect.bottom /nUnits ;

    int nEllipse = nUnits/3; // calculate how many to draw
    int nIndex ;             // current ellipse that is being draw

    CBrush brush ;       // bursh used for ellipse fill color
    CBrush *pBrushOld;     // previous brush that was selected into dc

    //draw ellipse , gradually moving towards upper-right corner
    for (nIndex = 0 ; nIndes < + nEllipse ; nIndes ++)
{
    //creat solid brush
    brush . CreatSolidBrush   (RGB ( ( (nIndex *byRed ) /nEllipse ).
               ( ( nIndex * byGreen ) /nEllipse ), ( (nIndex * byBlue) /nEllipse


    //select brush into dc
    pBrushOld= dc .SelectObject (&brhsh);

    //draw ellipse
    dc .Ellipse (  (int) fltStepHorz * 2, (int) fltStepVert * nIndex ,
         rect. right -( (int) fltStepHorz * nIndex )+ 1,
         rect . bottom -( (int) fltStepVert * (nIndex *2) ) +1) ;

    //delete the brush
    brush.DelecteObject ( );
    }
    }

    最后,处理WM_NCHITTEST消息,使当击打窗口的任何位置时能移动窗口。
UINT CRoundDlg : : OnNchitTest (Cpoint point )
{
    //Let user move window by clickign anywhere on the window .
    UINT nHitTest = CDialog : : OnNcHitTest (point) ;
    rerurn (nHitTest = = HTCLIENT)? HTCAPTION: nHitTest ;
    }
27、如何在代码中获取工具条和状态条的指针

    缺省时, 工作框创建状态条和工具条时将它们作为主框窗口的子窗口,状态条
有一个AFX_IDW_STATUS_BAR标识符,工具条有一个AFX_IDW_TOOLBAR标识符,下例说
明了如何通过一起调用CWnd: : GetDescendantWindow和AfxGetMainWnd来获取这些
子窗口的指针:
//Get pointer to status bar .
CStatusBar * pStatusBar =
    (CStatusBar *) AfxGetMainWnd ( ) —> GetDescendantWindow
(AFX_IDW_STUTUS_BAR);

//Get pointer to toolbar .
CToolBar * pToolBar =
    (CToolBar * ) AfxGetMainWnd ( ) —> GetDescendantWindow (AFX_IDW_TOOLBAR);
28、如何使能和禁止工具条的工具提示

    如果设置了CBRS_TOOLTIPS风格位,工具条将显示工具提示,要使能或者禁止
工具提示,需要设置或者清除该风格位。下例通过调用CControlBar : : GetBarStyle
和CControlBar : : SetBarStyle建立一个完成此功能的成员函数:
void CMainFrame : : EnableToolTips ( BOOL bDisplayTips )
{
    ASSERT_VALID  (m_wndToolBar);

    DWORD dwStyle = m _wndToolBar.GetBarStyle ( ) ;

    if (bDisplayTips)
         dwStyle |=CBRS_TOOLTIPS ;
    else
         dwStyle & = ~ CBRS_TOOLTIPS ;

    m_wndToolBar.SetBarStyle  (dwStyle );
}
29、如何设置工具条标题

    工具条是一个窗口,所以可以在调用CWnd : : SetWindowText来设置标题,
例子如下:
int CMainFrame : : OnCreate (LPCREATESTRUCT lpCreateStruct )
{

         …
    // Set the caption of the toolbar .
    m_wndToolBar.SetWindowText  (_T "Standdard");
30、如何创建和使用无模式对话框

    MFC将模式和无模式对话封装在同一个类中,但是使用无模式对话需要几
个对话需要几个额处的步骤。首先,使用资源编辑器建立对话资源并使用
ClassWizard创建一个CDialog的派生类。模式和无模式对话的中止是不一样的:
模式对话通过调用CDialog : : EndDialog 来中止,无模式对话则是调用
CWnd: : DestroyWindow来中止的,函数CDialog : : OnOK和CDialog : : OnCancel
调用EndDialog ,所以需要调用DestroyWindow并重置无模式对话的函数。
void CSampleDialog : : OnOK ( )
{
    // Retrieve and validate dialog data .
    if (! UpdateData (TRUE) )
    {
        // the UpdateData rountine will set focus to correct item
        TRACEO (" UpdateData failed during dialog termination .\n") ;
        return ;
    }

    //Call DestroyWindow instead of EndDialog .
    DestroyWindow ( ) ;
}

void CSampleDialog : : OnCancel ( )
{
    //Call DestroyWindow instead of EndDialog .
    DestroyWindow ( ) ;
}
    其次,需要正确删除表示对话的C++对象。对于模式对来说,这很容易,需要创
建函数返回后即可删除C++对象;无模式对话不是同步的,创建函数调用后立即返回,
因而用户不知道何时删除C++对象。撤销窗口时工作框调用CWnd : : PostNcDestroy,
可以重置该函数并执行清除操作,诸如删除this指针。
void CSampleDialog : : PostNcDestroy ( )
  {
    // Declete the C++ object that represents this dialog .
    delete this ;
}
    最后,要创建无模式对话。可以调用CDialog : : DoModal创建一个模式对放,
要创建一个无模式对话则要调用CDialog: : Create。下面的例子说明 了应用程序
是如何创建无模式对话的:
void CMainFrame : : OnSampleDialog  ( )
{
                                                                              
    // Declete the C++ object that represents this dialog .
    delete this ;
}
    最后,要创建无模式对话。可以调用CDialog : : DoModal创建一个模式对放,
要创建一个无模式对话则要调用CDialog: : Create。下面的例子说明 了应用程序
是如何创建无模式对话的:
void CMainFrame : : OnSampleDialog  ( )
    //Allocate a modeless dialog object .
    CSampleDilog * pDialog =new CSampleDialog ;
    ASSERT_VALID (pDialog) ;

    //Create the modeless dialog .
    BOOL bResult = pDialog —> Creste (IDD_IDALOG) ;
    ASSERT (bResult ) ;
}