MFC 技术点和问题点解析

1.代码实现树节点之间的跳转的方法

    void SetTreeNodeFocus(const int Type)
    {
        // 获取根节点

        HTREEITEM rootItem = m_TreeControl->GetRootItem();

        //获取子节点

        HTREEITEM Item = m_TreeControl->GetNextSiblingItem(rootItem);
        HTREEITEM pNode = m_TreeControl->GetChildItem(Item);

        //遍历子节点

        while(pNode != NULL)
        {

             //获取节点的ID
             int nType = (int)m_TreeControl->GetItemData(pNode);
             if (nType == Type)
            {

                //选中节点并且高亮显示
                m_TreeControl->SelectItem(pNode);
                return;
            }

           pNode = m_TreeControl->GetNextSiblingItem(pNode);
       }
}

 

2.打开文件对话框的同时打开到指定的路径

    //创建文件对话框

    CFileDialog dlg(TRUE,  _T("*.wav"), NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("WAV Files (*.wav)|*.wav||"));
    //已经获取到的路径

    std::wstring strPath = m_strPath; 

    //去掉路径中最后的文件名称

    size_t pos = strPath.find_last_of(L"\\");
    strPath = strPath.substr(0,pos);

    //把路径设置到对话框中

    dlg.m_pOFN->lpstrInitialDir = strPath.c_str();

 

 3.多语言支持中中文显示一串问号的问题

    问题现象:    应用程序界面上显示的Unicode字串显示成一串问号。  

    问题原因:    多语言支持的软件中字串需要用Unicode,但在编码过程中会涉及到宽字节(wstring)到窄字节(string)转化,当把宽字节转化成窄字节时丢失了Unicode字串的信息。

    问题解决:    Unicode字串显示过程中,从获取到的Unicode直接显示,不做宽字节(wstring)到窄字节(string)的转化。

 

4.查看动态连接库的导出函数

    在命令行中输入dumpbin /exports XXX.dll,就会显示出接口函数。

 

5.去掉对话框的内边框

   // 获取旧式样
   DWORD dwStyle = pdlg->GetStyle();

   dwStyle &= ~WS_BORDER;

   SetWindowLong(pdlg->m_hWnd, GWL_EXSTYLE, dwStyle);

 

6.应用程序打开新建邮件的界面并填写相关信息

   string strMail = "mailto:123@163.com";    //mailto:邮箱地址?subject=邮件主题&body=邮件正文
   ShellExecute(NULL, L"open", strMail.c_str(), NULL, NULL, SW_SHOWNORMAL);

 

7.编辑框控件根据内容自适应大小

   Rect MemoRect;

   m_pDetailEdit->GetWindowRect(&MemoRect);

   CString strText(_T(""));
   m_pEdit->GetWindowText(strText);

   int strLen = m_pEdit->GetWindowTextLength();

   HDC hDC = ::GetDC(m_pEdit->m_hWnd);

   CSize size;
   GetTextExtentPoint(hDC, strText, strLen, &size);

   ::SetWindowPos(m_pEdit->m_hWnd, NULL, MemoRect.left, MemoRect.top, MemoRect.right - MemoRect.left, (MemoRect.bottom - MemoRect.top + size.cy),SWP_NOMOVE);
   ::ReleaseDC(m_pEdit->m_hWnd, hDC);

8.模态对话框显示的时候设置默认的焦点

   把对话框最后的return TRUE修改为return FALSE。

   然后再创建对话框中的控件时第一个创建默认显示焦点的控件。

 

9.对话框上设置静态分割线

    静态创建:在资源中手动拖动一个图片控件并且设置空间的类型为ETCHEDHORZ,或者手动拖动修改控件的大小为一条线。

    动态创建:new CStatic,然后调用Create,设置属性为SS_ETCHEDHORZ。

 

10.设置按钮按下的状态

    CButton* pButton->SetState(TRUE)    //设置按钮为按下的状态

    CButton* pButton->SetState(FALSE)  //取消按钮按下的状态

11.下拉框默认 显示空,点击选择时才显示特定的值

要combox在程序运行的时候edit中不显示的方法有2种:

    直接添加信息。其他什么都不用做。这样开始就是空的,只有选择了,才显示出来,例如。

     m_combox1.AddString(_T("1"));

     m_combox1.AddString(_T("2"));

     m_combox1.AddString(_T("3"));

12.刷新控件

    CRect Rect;
    m_pButton->GetWindowRect(&Rect);
    ScreenToClient(&Rect);
   InvalidateRect(&Rect);

13.静态文本控件能够响应点击操作

    在创建控件时添加SS_NOTIFY与SS_NOPREFIX属性

14.静态文本控件贴png图片

    在创建控件时添加SS_BITMAP属性SS_NOTIFY

    CImage m_Icon.Load(wstring(L"tupian.png").c_str());
    RECT rect;
    HDC pDC = ::GetWindowDC(pImageStatic->m_hWnd);
    ::GetWindowRect(pImageStatic->m_hWnd,&rect);
    m_Icon.TransparentBlt(pDC,rect,RGB(255,255,255));
    pImageStatic->SetBitmap(m_Icon);
    pImageStatic->ShowWindow(SW_SHOW);
    ::ReleaseDC(pImageStatic->m_hWnd,pDC);
15.静态文本控件贴bmp图片

    在创建控件时添加SS_BITMAP与SS_NOTIFY属性

    HBITMAP m_Icon = (HBITMAP)::LoadImage( NULL,L"tupian.bmp").c_str(), IMAGE_BITMAP, 21,21, LR_LOADFROMFILE);
    m_pImageStatic->SetBitmap(m_Icon);
    m_pImageStatic->ShowWindow(SW_SHOW);

16.静态文本控件贴ico图片

    在创建控件时添加SS_ICON与SS_CENTERIMAGE属性
    HICON m_Icon = (HICON)::LoadImage( NULL,(L"tupian.ico").c_str(), IMAGE_ICON, 16,16, LR_LOADFROMFILE);

    m_pImageStatic->SetIcon(m_Icon);

 17.设置对话框中控件颜色和背景

HBRUSH CDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
 HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

 // TODO: Change any attributes of the DC here
 switch(pWnd->GetDlgCtrlID())
 { 
 case ID_STATUS_NUM:
  {
   pDC->SetBkMode(TRANSPARENT);     //设置透明
   pDC->SetTextColor(RGB(150,150,150));    //设置字体
   pDC->SetBkColor(RGB(255,255, 255));    //设置背景色
   break;
  }
 default:
  break;
 }
   
   return (HBRUSH)GetStockObject(HOLLOW_BRUSH);
}

18.过滤对话框中的背景颜色

    SetWindowLong(this->GetSafeHwnd(),GWL_EXSTYLE,
    GetWindowLong(this->GetSafeHwnd(),GWL_EXSTYLE)|0x80000);

    HINSTANCE hInst = LoadLibrary(L"User32.DLL");
    if(hInst)
    {           
          typedef BOOL (WINAPI *MYFUNC)(HWND,COLORREF,BYTE,DWORD);         
          MYFUNC fun = NULL;
          //取得SetLayeredWindowAttributes函数指针    
         fun=(MYFUNC)GetProcAddress(hInst, "SetLayeredWindowAttributes");
         if(fun)
        {
            fun(this->GetSafeHwnd(),RGB(100,100,100),10,1);     //100,100,100 是要过滤的颜色
        }
  
       FreeLibrary(hInst); 
   }

 19.更新对话框的主背景bmp图片

BOOL CDlg::OnEraseBkgnd(CDC* pDC)
{
 CRect rect; 
 CDC   memDC; 
 CBitmap* pOldMemBmp = NULL;

 GetWindowRect(&rect); 

 CBitmap* pBitmap = NULL;
 CImage image;
 
 image.Load(m_ImagePath.c_str());   //更新背景只需要更新此处的背景图片的路径

 HBITMAP hbmp = image.Detach();
 pBitmap = CBitmap::FromHandle(hbmp);

 memDC.CreateCompatibleDC(pDC); 
 pOldMemBmp = memDC.SelectObject(pBitmap); 
 pDC->BitBlt(0,0,rect.Width(),rect.Height(),&memDC,0,0, SRCCOPY); 
 if(pOldMemBmp)
 {
  memDC.SelectObject(pOldMemBmp);
 }

 image.Destroy();
 DeleteObject(pBitmap);
 DeleteObject(hbmp);
 memDC.DeleteDC();
 return   TRUE;

}

20.创建鼠标滑动弹出按钮

    需要包含的头文件和库

    #include <vector>
    #include <sstream>

    #pragma comment(lib,"gdiplus.lib")

    配置图片和大小

    <Dockbardown name="Dockbardown">
       <Dockbackground name="background" id="0" rect="0 387 866 502" imageNormal="background.png" imageText="background.png"/>
        <Dockimage name="1" id="1" rect="130 105 186 161" imageNormal="1.png" imageText="1-1.png"/>
        <Dockimage name="2" id="2" rect="196 105 252 161" imageNormal="2.png" imageText="2-1.png"/>
       </Dockbardown>

   定义类

class TDocItem
{
public:
 TDocItem(std::wstring wstrPicFile, std::wstring wstrTextPicFile, int id, RECT rect)
 {
  Icon = NULL;
  IconPath = wstrPicFile;
  if (IconPath != L"")
  {
   Icon = new Gdiplus::Bitmap(IconPath.c_str());
  }

  TextIcon = NULL;
  TextIconPath = wstrTextPicFile;
  if (wstrTextPicFile != L"")
  {
   TextIcon = new Gdiplus::Bitmap(TextIconPath.c_str());
  }

  m_id = id;

  Y = rect.top;
  X = rect.left;
  Width = rect.bottom - rect.top;
  Height = rect.bottom - rect.top;
  CentreX =  X + Width / 2;
  CentreY = Y + Height / 2;
 }

 Gdiplus::Bitmap *Icon;
 Gdiplus::Bitmap *TextIcon;

 std::wstring IconPath;
 std::wstring TextIconPath;

 int m_id;
 int X;
 int Y;
 int Width;
 int Height;
 int CentreX;
 int CentreY;
};

   创建背景和按钮

 GdiplusStartupInput gdiplusStartupInput;
 ULONG_PTR gdiplusToken;
 GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

 // 设置图片的背景
 TiXmlElement * layoutElement = pElement->FirstChildElement();

 if (layoutElement != NULL)
 {
  string strImagePath = layoutElement->Attribute("imageNormal");

  m_BackPG = wstrImagePath;

  string strrect = layoutElement->Attribute("rect");

  RECT rect = {0,0,0,0};

  stringstream strStream(strrect);

  strStream >> rect.left >> rect.top >> rect.right >> rect.bottom;

  int m_BKWidth = rect.right - rect.left;
  int m_BKHeight = rect.bottom - rect.top;

  int m_BKPosX = rect.top;
 }

 // 设置图片的参数信息
 layoutElement = layoutElement->NextSiblingElement();
 while(layoutElement != NULL)
 {
  string ID = layoutElement->Attribute("id");

  string strrect = layoutElement->Attribute("rect");

  RECT rect = {0,0,0,0};
  stringstream strStream(strrect);
  strStream >> rect.left >> rect.top >> rect.right >> rect.bottom;

  string strImageNormalPath = layoutElement->Attribute("imageNormal");
  wstring wstrImageNormalPath = L"";
  wstrImageNormalPath = wstrImageNormalPath;

  string strImageTextPath = layoutElement->Attribute("imageText");
  wstring wstrImageTextPath = L"";
  wstrImageTextPath = wstrImageTextPath;

  TDocItem AItem(wstrImageNormalPath, wstrImageTextPath, atoi(ID.c_str()),rect);
  std::vector<TDocItem> m_DocItems.push_back(AItem);

  layoutElement = layoutElement->NextSiblingElement();
 }

 int m_ImageWidth = m_DocItems[0].Width;

整体描绘

void  CDlg::PaintBackGround(int X, int Y)
{
 if (m_BackPG == L"")
 {
  return;
 }

 Bitmap *imageBK = new Bitmap(m_BackPG.c_str(),false);

 Bitmap * imageface= new Bitmap (m_BKWidth, m_BKHeight);

 Gdiplus::Graphics *g = Gdiplus::Graphics ::FromImage(imageface);

 g->SetSmoothingMode(SmoothingModeAntiAlias);

 g->DrawImage(imageBK, 0, 0, imageBK->GetWidth(), imageBK->GetHeight());

 DrawButtons(g, X, Y);

 //贴图
 HBITMAP  pbitmap = NULL;

 CDC *pCDC=GetDC();
 CDC pMemDC;

 pMemDC.CreateCompatibleDC(pCDC);

 imageface->GetHBITMAP(Color(ARGB(0)),&pbitmap);

 HGDIOBJ  oldBitmap = pMemDC.SelectObject(pbitmap);

 ::BitBlt(pCDC->GetSafeHdc(), 0, m_BKPosX, imageBK->GetWidth(), imageBK->GetHeight(), pMemDC.GetSafeHdc(), 0, 0, SRCCOPY );

 ReleaseDC(pCDC);

 pMemDC.SelectObject(oldBitmap);

 DeleteDC(pMemDC.GetSafeHdc());
 DeleteObject(pbitmap);

 delete imageBK;
 delete imageface;
 delete g;
}

 

描绘按钮

void CDlg::DrawButtons(Gdiplus::Graphics *g,int CurX,int CurY)

 int pZoom = 0;
 int pZoomY = 0;
 int pX = m_DocItems[0].X;
 int pMax = m_ImageWidth * 1.9;

 for(UINT i = 0; i < m_DocItems.size(); i++)
 {      
  m_DocItems[i].X = pX;

  if (CurX == 0 && CurY == 0)
  {
   pZoom = m_ImageWidth;
  }
  else
  {
   pZoom =  pMax - abs(CurX - m_DocItems[i].CentreX);
  }

  if ( pZoom > pMax )
  {
   pZoom = pMax;
  }

  if ( pZoom < m_ImageWidth)
  {
   pZoom = m_ImageWidth;
  }

  m_DocItems[i].Width = pZoom;
  m_DocItems[i].Height = pZoom;
  pX = pX + m_DocItems[i].Width + 10;

  if((pX- m_DocItems[i].Width - 10 < CurX) && (CurX < pX) && (CurX != 0) && (CurY != 0))
  {
   g->DrawImage(m_DocItems[i].TextIcon, m_DocItems[i].X, m_DocItems[i].Y - m_DocItems[i].Height, m_DocItems[i].Width, m_DocItems[i].Height);
  }
  else
  {
   g->DrawImage(m_DocItems[i].Icon, m_DocItems[i].X, m_DocItems[i].Y - m_DocItems[i].Height, m_DocItems[i].Width, m_DocItems[i].Height);
  }
 }
}

鼠标移动

void CDlg::OnMouseMove(UINT nFlags, CPoint point)
{
 CDialog::OnMouseMove(nFlags, point);

 if(point.y < m_BKPosX)
 {
  PaintBackGround( 0,0 ) ;

  m_CurX = 0;
  m_CurY = 0;
 }
 else
 {
  PaintBackGround( point.x, point.y ) ; 

  m_CurX = point.x;
  m_CurY = point.y;
 }
}

 21.刷新桌面应用程序

 HWND hWnd = ::GetDesktopWindow();  
 hWnd   =   ::FindWindowEx(hWnd,   0,   L"Progman",  0); 
 hWnd   =   ::FindWindowEx(hWnd,   0,   L"SHELLDLL_DefView",   0);  
 hWnd   =   ::FindWindowEx(hWnd,   0,   L"SysListView32",   0); 

 ::PostMessage(hWnd,WM_KEYDOWN,VK_F5,0);  
 ::PostMessage(hWnd,WM_KEYUP,VK_F5,0);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值