zoukankan      html  css  js  c++  java
  • (转)MFC技巧学习<五>

    51. 如何获得其他程序的图标,并显示在View中
     [问题提出]
     有的时候,如:类资源管理器会遇到获得程序图标并显示的操作,如何实现呢?
     [解决方法]
     SDK函数SHGetFileInfo来获得有关文件的很多信息:如大小图标,属性,类型等.
     [程序实现]
     建立名为My的SDI工程.在OnPaint()函数中加入:

     void CMyView::OnPaint() 
     {
      CPaintDC dc(this); // device context for painting
      HICON hIcon=:: ExtractIcon(AfxGetInstanceHandle(),_T("NotePad.exe"),0); 
      if (hIcon && hIcon!=(HICON)-1) 
      dc.DrawIcon(10,10,hIcon); 
      // TODO: Add your message handler code here
      // Do not call CView::OnPaint() for painting messages
     }


     说明:_T("NotePad.exe")指的是要获得什么程序的图标.
     或者在OnDraw()中(此时必须保证没有OnPaint()函数,想想为何?)

     void CMyView::OnDraw(CDC* pDC)
     {
      CMyDoc* pDoc = GetDocument();
      ASSERT_VALID(pDoc);
      // TODO: add draw code for native data here
      HICON hIcon=:: ExtractIcon(AfxGetInstanceHandle(),_T("NotePad.exe"),0); 
      if (hIcon &&hIcon!=(HICON)-1) 
      pDC->DrawIcon(10,10,hIcon); 
     }


    52 .RichEdit
    在Dialog(FormView中打开)中加入CRichEdit控件后,这个dialog 为什么打不开如何处理?
     [解决方法]
     在函数:InitInstance的第一句加入AfxInitRichEdit();

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

    54. 如何改变窗口标题?
     [问题提出]
      在应用程序的不同运行时期,要反映当前状态往往会修改应用程序标题.
     [解决方法]
      在MFC类库中提供了CWnd::SetWindowText函数,通过该函数可以改变任何窗体(包括控件)的标题.
      改变主窗体的标题:

      CWnd *m_pMainWnd;
      m_pMainWnd=AfxGetMainWnd();
      m_pMainWnd->SetWindowText(_T("改变标题"));

    当改变多视MDI的子窗口的标题时,用:

    GetParentFrame()->SetWindowText(_T("MDI Child改变标题"));

      当改变按钮的标题时(假设按钮的ID=IDC_BUTTON1):

      GetDlgItem(IDC_BUTTON1)->SetWindowText(_T("Button 改变标题"));
    

      运行看看.

    55.图标透明
    (1).Windows中的图标其实是有两个图像组成的,其中一个用于与它要显示的位置的图像做“AND”操作,另一个作“XOR”操作。
    透明:用“白色”AND,用“黑色”XOR
    反色:用“白色”AND,用“白色”XOR
    正常色:用“黑色”AND,用正常颜色XOR.
    (2). WIN9X中好像是对像素的操作实现透明的
    WIN2K中就有API直接实现透明了!
    WIN2K中
    GetWindowLong
    SetWindowLong
    SetLayeredWindowAttributes
    三个API就可以实现透明了!
    (3)

    ::DrawIconEx(pDC->GetSafeHdc(),point.x,point.y,icon,icosize,icosize,0,NULL,DI_NORMAL);


    56.ASSERT()是干什么用的
    ASSERT()是一个调试程序时经常使用的宏,在程序运行时它计算括号内的表达式,如果表达式为FALSE (0), 程序将报告错误,并终止执行。如果表达式不为0,则继续执行后面的语句。这个宏通常原来判断程序中是否出现了明显非法的数据,如果出现了终止程序以免导致严重后果,同时也便于查找错误。例如,变量n在程序中不应该为0,如果为0可能导致错误,你可以这样写程序:
      ......
      ASSERT( n != 0);
      k = 10/ n;
      ......
      ASSERT只有在Debug版本中才有效,如果编译为Release版本则被忽略。
      assert()的功能类似,它是ANSI C标准中规定的函数,它与ASSERT的一个重要区别是可以用在Release版本中。

    56. 将RADIO控件初始状态设置成为选中
    1、"在OnInitialDialog中用CButton::CheckRadioButton(...)
    2、"在OnInitialDialog中用CButton::SetCheck(...)
    3、"关联一个整型值,在构造函数中设为0。


    57.获得视图

    CFrameWnd* pFrameWnd = (CFrameWnd*)theApp.GetMainWnd();
    CMyView* pView = (CMyView*)pFrameWnd->GetActiveView();


    58.如何得到屏幕的真实尺寸
    [问题提出]
    我的屏幕是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();
    }


    59. 修改标题栏高度
    NONCLIENTMETRICS nm
    调用SystemParametersInfo(SPI_GETNONCLIENTMETRICS,sizeof(nm),&nm,0)
    重设SystemParametersInfo(SPI_SETNONCLIENTMETRICS,sizeof(nm),&nm,0)

    60. 如何实现“气球式”工具提示。
    本程序介绍一个与CToolTipCtrl相似的类CTooolTipWnd。
    使用该类的方法如下:
    1. 增加ToolTipWnd.cpp到工程文件。
    2. 在头文件中添加#include "ToolTipWnd.h" 。 
    3. 在类声明中添加:
    CToolTipWnd m_BalloonToolTip;
    4. 在OnInitDialog(对话框)或OnInitialUpdate(表单视)中添加下面代码:

      m_BalloonToolTip.Create(this); 
      m_BalloonToolTip.AddTool(GetDlgItem(), , [text color]); 
    eg.
      m_BalloonToolTip.AddTool(GetDlgItem(IDC_EDIT1),"Tooltip", RGB(255,0,0)); 
    
      第三个参数为可选,缺省为RGB(0, 0, 0)。缺省文本颜色可以用SetDefTextColor进行设置。
    4. 重载PreTranslateMessage并添加下面代码:
      if(m_BalloonToolTip) 
        m_BalloonToolTip.RelayEvent(pMsg);

     

    61. dlg 上建立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);
    ...............
    }


    62. 窗口最大化、最小化及关闭的消息是什么?如何截获?
    最大化、最小化将发送WM_SYSCOMMAND消息。要处理该消息,可以这么做:
      1、在Form的头文件中添加:

       void __fastcall RestrictMinimizeMaximize(TMessage &Msg); 
       BEGIN_MESSAGE_MAP 
       MESSAGE_HANDLER(WM_SYSCOMMAND, TMessage, RestrictMinimizeMaximize) 
       END_MESSAGE_MAP(TForm) 


      2、在Form的单元文件中添加:

       void __fastcall TForm1::RestrictMinimizeMaximize(TMessage& Msg) 
       { 
       if (Msg.WParam == SC_MINIMIZE) 
       { 
       //catches minimize... 
       } 
       else if (Msg.WParam == SC_MAXIMIZE) 
       { 
       //catches maximize... 
       } 
       TForm::Dispatch(&Msg); 
       // or "else TForm::Dispatch(&Msg)" to trap 
       } 

      关闭窗口的消息为WM_CLOSE,C++Builder提供了OnClose事件。


    63. 如何遍历整个目录树查找文件
    在应用程序的开发过程中,会遇到如何查找某一文件以确定此文件路径的问题。利用CFileFind类可以比较方便地在当前目录下进行文件查找,但却不能对其子目录中的文件进行搜寻。而实际应用中往往需要对某一整个目录树,甚至是整个C盘或D盘驱动器进行文件搜寻。通过实践,我们在Visual C++ 6.0中编程实现了如何遍历任意目录树,以查找某一特定的文件。
      在下面的具体陈述中可以看到,在确定要查找的文件名和要进行搜索的目录的名称后,将调用函数Search_Directory进行文件的查找。首先依次查找当前目录下的每一个实体(文件或是子目录),如果是某一子目录,则进入该子目录并递归调用函数Search_Dirctory进行查找,查找完毕之后, 再返回上一级目录;如果不是子目录而是某一文件,则判断其是否就是我们要查找的文件,如果是则输出其完整的文件路径。这样,通过Search_Directory函数的反复递归调用,就可以实现对整个目录,包括子目录的遍历搜索。下面将举例详细讲述如何在VC++中编程实现在整个目录树中的文件查找。
      1. 在Visual C++ 6.0(VC++ 5.0与之类似)中用默认方式创建了一基于对话框的应用程序Search。在主窗口对话框上放置一命令按钮,其Caption为“Search File”,ID为ID_BUTTON_SEARCH。单击此按钮将完成文件的查找工作。
      2. 利用ClassWizard为“Search File”按钮的BN_CLICKED 事件添加处理函数OnButtonSearch,代码如下:

    #include 〈direct.h〉
    #include 〈io.h〉 
    void CSearchDlg::OnButtonSearch() 
    { 
      // TODO: Add your control notification handler code here 
      char szFilename[80]; 
      // 字符串 szFilename 表示要查找的文件名 
      strcpy(szFilename,"Mytext.txt"); 
      _chdir("d:\\"); // 进入要查找的路径(也可为某一具体的目录) 
      // 查找文件, 如果查到则显示文件的路径全名 
      Search_Directory(szFilename); 
      // 为CSearchDlg类的一成员函数 
      MessageBox(″查找文件完毕!″); 
      // 显示查找完毕的信息 
    } 

      3. 在CSearchDlg类中增加成员函数Search_Directory,它将完成具体的文件查找工作,代码如下:

    void CSearchDlg::Search_Directory(char* szFilename)
    { 
      long handle; 
      struct _finddata_t filestruct;
      //表示文件(或目录)的信息
      char path_search[_MAX_PATH]; 
      //表示查找到的路径结果 
      // 开始查找工作, 找到当前目录下的第一个实体(文件或子目录), 
      // "*"表示查找任何的文件或子目录, filestruct为查找结果 
      handle = _findfirst("*", &filestruct); 
      // 如果handle为-1, 表示当前目录为空, 则结束查找而返回 
      if((handle == -1)) return; 
      // 检查找到的第一个实体是否是一个目录(filestruct.name为其名称) 
      if( ::GetFileAttributes(filestruct.name) & FILE_ATTRIBUTE_DIRECTORY ) 
      { 
       // 如果是目录, 则进入该目录并递归调用函数Search_Dirctory进行查找, 
       // 注意: 如果目录名的首字符为'.'(即为"."或".."), 则不用进行查找 
       if( filestruct.name[0] != '.' ) 
       { 
         _chdir(filestruct.name); 
         Search_Directory(szFilename); 
         // 查找完毕之后, 返回上一级目录 
         _chdir(".."); 
       } 
      } 
      else // 如果第一个实体不是目录, 则检查是否是要查找的文件 
      { 
       // stricmp对两字符串进行小写形式的对比, 返回为0表示完全一致 
       if( !stricmp(filestruct.name, szFilename) ) 
       { 
         // 先获得当前工作目录的全路径 
         _getcwd(path_search,_MAX_PATH); 
         // 再获得文件的完整的路径名(包含文件的名称) 
         strcat(path_search,"\\"); 
         strcat(path_search,filestruct.name); 
         MessageBox(path_search); //输出显示 
       } 
      } 
      // 继续对当前目录中的下一个子目录或文件进行与上面同样的查找 
      while(!(_findnext(handle,&filestruct))) 
      { 
       if( ::GetFileAttributes(filestruct.name) & FILE_ATTRIBUTE_DIRECTORY ) 
       { 
         if(*filestruct.name != '.') 
         { 
          _chdir(filestruct.name); 
          Search_Directory(szFilename); 
          _chdir(".."); 
         } 
       } 
       else 
       { 
         if(!stricmp(filestruct.name,szFilename)) 
         { 
          _getcwd(path_search,_MAX_PATH); 
          strcat(path_search,"\\"); 
          strcat(path_search,filestruct.name); 
          MessageBox(path_search); 
         } 
       } 
      } 
      _findclose(handle); 
      // 最后结束整个查找工作 
    } 
    

      这样我们就可以对整个目录进行遍历搜索,查找某一特定的文件,并输出显示其完整的文件路径。以上的程序在Visual C++ 6.0中已调试通过。


    64. Richedit control的设置背景图片办法
    1:继承CRichEditCtrl::OnEraseBkgnd(CDC* pDC)消息事件中,给Richedit控件绘制上背景图片:

    m_bmpBackground.DrawDIB(pDC, 0, 0, rc.Width(), rc.Height());

    当然也可以通过subclass richedit window之后,在回调函数中处理WM_ERASEBKGND消息。
    2:设置了Richedit控件的透明属性;
    3:依照kenwhale所说的,Hook了GDI32.DLL中的ExtTextOut函数,将RichEdit的text-output options去除ETO_OPAQUE style。综上所述,即可实现RichEdit控件的背景图片效果。
    据此,我还实现了RichEdit控件背景绘制AVI动画效果。

    65. MFC程序中如何创建多级目录

    BOOL mkdirEx(const char* lpPath)
    {
    CString pathname = lpPath;
    if(pathname.Right(1) != "\")
    pathname += "\" ;
    int end = pathname.ReverseFind('\');
    int pt = pathname.Find('\');
    if (pathname[pt-1] == ':')
    pt = pathname.Find('\', pt+1);
    CString path;
    while(pt != -1 && pt<=end)
    {
    path = pathname.Left(pt+1);
    if(_access(path, 0) == -1)
    _mkdir(path);
    pt = pathname.Find('\', pt+1);
    }
    return true;
    }

  • 相关阅读:
    找回Android studio的帮助文档
    adb shell 命令详解
    Android 获取Activity当前view
    下载网络文件HttpURLConnection.getContentLength()大小为 0
    Android设置屏幕旋转后保存数据
    解决TextView drawableRight左侧图片大小不可控的问题
    Android全屏(包含3种隐藏顶部状态栏及标题栏和一种隐藏Android 4.0平板底部状态栏的方法)
    人生苦短,我用Python(目录)
    爬虫学习目录
    Django-jet自定义菜单
  • 原文地址:https://www.cnblogs.com/leven20061001/p/2728176.html
Copyright © 2011-2022 走看看