ZhangJie Software Development Engineer

MFC开发笔记

2023-08-25
ZhangJie
MFC

MFC开发笔记。

MFC常用代码

  • 获取CTabCtrl选中标签页上的文本
void CXXDlg::OnXXTabSelChange(NMHDR* pNMHDR, LRESULT* pResult)
{
    *pResult = 0;
    int nCurSel = m_xxTabCtrl.GetCurSel();

    TCITEM tcItem;
    // Get the current tab item text
    enum { MAX_BUF_LEN = 128 };
    TCHAR buffer[MAX_BUF_LEN] = {0};
    tcItem.pszText = buffer;
    tcItem.cchTextMax = MAX_BUF_LEN;
    tcItem.mask = TCIF_TEXT;
    m_xxTabCtrl.GetItem(nCurSel, &tcItem);

    tcItem.pszText;
}
  • 修改CTabCtrl背景色
// CTabCtrlST.h
class CTabCtrlST : public CTabCtrl
{
public:
    CTabCtrlST();
    virtual ~CTabCtrlST();

public:
    virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
    
protected:
    afx_msg BOOL OnEraseBkgnd(CDC* pDC);
    afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct);
    COLORREF m_colorBK;
    DECLARE_MESSAGE_MAP()

public:
    void SetTabBk(COLORREF crColor);
};
// CTabCtrlST.cpp
CTabCtrlST::CTabCtrlST() : m_colorBK(ColorBlue)
{
}

CTabCtrlST::~CTabCtrlST()
{
}

BEGIN_MESSAGE_MAP(CTabCtrlST, CTabCtrl)
    ON_WM_DRAWITEM()
    ON_WM_ERASEBKGND()
END_MESSAGE_MAP()

void CTabCtrlST::SetTabBk(COLORREF crColor)
{
    m_colorBK = crColor;
    this->Invalidate();
}

void CTabCtrlST::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
    CTabCtrl::OnDrawItem(nIDCtl, lpDrawItemStruct);
}

void CTabCtrlST::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
    CBrush brushBK(m_colorBK);
    char szTabText[100];
    UINT bkColor;
    CBrush* cbr;
    TC_ITEM tci;
    LOGBRUSH m_LogBrush;
    cbr = &brushBK;
    cbr->GetLogBrush(&m_LogBrush);
    bkColor = m_LogBrush.lbColor;
    memset(szTabText, '/0',  sizeof(szTabText));
    tci.mask = TCIF_TEXT;
    tci.pszText = szTabText;
    tci.cchTextMax = sizeof(szTabText) - 1;
    GetItem(lpDrawItemStruct->itemID, &tci);
    FillRect(lpDrawItemStruct->hDC, &lpDrawItemStruct->rcItem, *cbr);
    ::SetBkColor(lpDrawItemStruct->hDC, bkColor);
    TextOut(lpDrawItemStruct->hDC,
            lpDrawItemStruct->rcItem.left + 5,
            lpDrawItemStruct->rcItem.top + 5,
            tci.pszText,
            lstrlen(tci.pszText));
}

BOOL CTabCtrlST::OnEraseBkgnd(CDC* pDC)
{
    CBrush brushBK(m_colorBK);
    CRect rect;
    this->GetClientRect(rect);
    pDC->FillRect(rect, &brushBK);
    return TRUE;
}
  • 热键
// dlg.h

#define ONMYKEY 0x00001
afx_msg void OnHotKey(UINT nHotKeyId, UINT nKey1, UINT nKey2);

// dlg.cpp
BEGIN_MESSAGE_MAP(CMFCApplication3Dlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
    ON_WM_HOTKEY()
END_MESSAGE_MAP()


BOOL CMFCApplication3Dlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// TODO: 在此添加额外的初始化代码

    RegisterHotKey(GetSafeHwnd(), ONMYKEY, NULL, VK_F10);

	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

void CMFCApplication3Dlg::OnHotKey(UINT nHotKeyId, UINT nKey1, UINT nKey2)
{
    // TODO: 在此添加消息处理程序代码和/或调用默认值

    MessageBox(_T("你按下了F10键"));
    CDialogEx::OnHotKey(nHotKeyId, nKey1, nKey2);
}
  • 多线程 & 事件
// xx.h
{
    private:
        static void ProcessThread(LPVOID data);
        void Process();
    
    private:
        HANDLE m_hStart;
        HANDLE m_hStop;
        HANDLE m_hProcessThread;
        int m_number;
        BOOL m_processing;
}

// xx.cpp
{
    m_number = 0;

    m_processing = FALSE;

    m_hStart = CreateEvent(NULL, FALSE, FALSE, NULL);
    m_hStop = CreateEvent(NULL, TRUE, FALSE, NULL);

    UINT threadId = 0;
    m_hProcessThread = (HANDLE)_beginthreadex(NULL, 0, (unsigned (__stdcall *)(void *))ProcessThread, this, 0, &threadId);
    if (NULL == m_hProcessThread || INVALID_HANDLE_VALUE == m_hProcessThread)
    {
        m_hProcessThread = INVALID_HANDLE_VALUE;
    }
}

void CTestThreadDlg::OnBnClickedButtonStart()
{
    SetEvent(m_hStart);
    m_processing = !m_processing;
}

void CTestThreadDlg::OnBnClickedButtonStop()
{
    // SetEvent(m_hStop);
    m_processing = FALSE;
}

void CTestThreadDlg::ProcessThread( LPVOID data )
{
    CTestThreadDlg* pTestThreadDlg = (CTestThreadDlg*)data;
    BOOL bStop = FALSE;
    int iWait = 0;
    int iLoop = 0;
    HANDLE handleArray[2];
    handleArray[0] = pTestThreadDlg->m_hStart;
    handleArray[1] = pTestThreadDlg->m_hStop;

    CString csData = "";
    while (bStop == FALSE)
    {
        switch (WaitForMultipleObjects(2, handleArray, FALSE, INFINITE))
        {
        case WAIT_OBJECT_0:  // 接收到start事件
            {
                TRACE("-->recv start signal...\n");
                pTestThreadDlg->Process();
                break;
            }
        case WAIT_OBJECT_0 + 1:  // 接收到stop事件
            {
                TRACE("-->recv stop signal...\n");
                bStop = TRUE;
                break;
            }
        case WAIT_TIMEOUT:
            {
                iWait = 1000;
                iLoop += 1;
                TRACE("-->WAIT_TIMEOUT....\n");
                break;
            }
        default:
            break;
        }
    }
    _endthreadex(0);
}

void CTestThreadDlg::Process()
{
    while(m_processing)
    {
        ++m_number;
        TRACE("-->m_number = %d\n", m_number);
        Sleep(500);
    }
}
  • MFC html Dialog
    BOOL CXXDlg::OnInitDialog() {
      // ...
      CDHtmlDialog::Navigate("file:///E:/a.html");
      // ...
    }
    
  • MFC确保实例唯一性
    BOOL CTestApp::InitInstance()
    {
      HANDLE hAppMutex = CreateMutex(NULL, TRUE, "CTestAppInstance");
      if (GetLastError() == ERROR_ALREADY_EXISTS)  
      {
          CloseHandle(hAppMutex);
          hAppMutex = NULL;
          return FALSE;
      }
        
      // ...
    }
    
  • MFC创建目录
    CString str = "D:\\a1";
    if (!PathIsDirectory(str))
    {
      ::CreateDirectory(str, NULL);  //创建目录,已有的话不影响
    }
    str += "\\b1";
    if (!PathIsDirectory(str))
    {
      ::CreateDirectory(str, NULL); //创建目录,已有的话不影响
    }
    
  • MFC获取当前路径
    char pFileName[MAX_PATH]; 
    int nPos = GetCurrentDirectory( MAX_PATH, pFileName); 
    CString csFullPath(pFileName);  
    
  • MFC判断是否有效路径 ```cpp std::string ppath = “C:”;

if (!PathIsDirectory(ppath.c_str())) ```


上一篇 git and svn

Comments

Content