首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

個人考勤軟體開發實例(更新版 2.1):解決列印預覽工具列按鈕狀態更新問題

     編輯:關於VC++

更新說明:v2.0 發布後收到回饋,發現列印預覽視窗中工具列按鈕命令狀態無法更新。v2.1 已修復此問題(見第 10 點說明),並補充文件說明。

本軟體為對話方塊型個人考勤工具,功能:

  • 從系統時鐘取得時間,上下班點擊欄位標題記錄工時
  • 按月統計彙總、按年建檔、歷史記錄查詢、月報表列印
  • 年彙總欄可選擇檢視/列印特定月份

非標準 MFC 實現列印/列印預覽架構

對話方塊型應用原無 CFrameWnd/CView,為實現列印功能,採用「子框架+子視圖」嵌入主對話方塊的非常規架構(參考《Visual C++ 程式設計高手》範例 18-05 改良)。

關鍵實作步驟

  1. InitInstance 建立主對話方塊並保存指標
    CAttendanceDlg dlg;
    m_pMainWnd = &dlg;
    m_pMiddle = &dlg; // 備份主視窗指標
  2. 主對話方塊 OnCreate 建立子框架 CChildFrame
    CChildFrame* pFrame = new CChildFrame;
    m_pChildFrame = pFrame;
    pFrame->LoadFrame(IDR_MAINFRAME, WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL, NULL);
    pFrame->ShowWindow(SW_HIDE); // 初始隱藏
  3. 子框架 OnCreate 建立子視圖 CChildView
    CCreateContext ctx;
    ctx.m_pNewViewClass = RUNTIME_CLASS(CChildView);
    ctx.m_pCurrentFrame = this;
    m_pView = STATIC_DOWNCAST(CChildView, CreateView(&ctx));
    if (m_pView) { m_pView->ShowWindow(SW_HIDE); SetActiveView(m_pView); }
  4. 主對話方塊列印/預覽處理:向子框架發送命令
    // 列印
    m_pChildFrame->SendMessage(WM_COMMAND, ID_FILE_PRINT);
    // 預覽
    m_pChildFrame->ShowWindow(SW_SHOW);
    m_pChildFrame->SendMessage(WM_COMMAND, ID_FILE_PRINT_PREVIEW);
  5. 子框架預覽處理:暫時替換 m_pMainWnd
    CAttendanceApp* app = (CAttendanceApp*)AfxGetApp();
    app->m_pMainWnd = this; // 臨時替換
    m_pView->ShowWindow(SW_SHOW);
    SetActiveView(m_pView);
    m_pView->OnFilePrintPreview(this);
  6. 預覽結束:恢復狀態與 m_pMainWnd
    pParent->ShowWindow(SW_HIDE);
    pParent->UpdateWindow();
    app->m_pMainWnd = app->m_pMiddle; // 恢復主對話方塊
    app->m_pMiddle->UpdateWindow();

    置於 CWrapperView::OnEndPrintPreview 結尾。

  7. 子框架菜單資源 IDR_MAINFRAME 僅含列印/預覽兩項
  8. 列印內容與版面配置於 CChildView::OnDraw(CDC* pDC) 實作
  9. CAttendanceApp::SetPrntOrientation() 強制設定直向列印(橫向改 DMORIENT_LANDSCAPE)

v2.1 關鍵修復:列印預覽工具列按鈕狀態更新

問題成因:子框架/子視圖成為對話方塊子物件後,UPDATE_COMMAND_UI 訊息路由受阻,導致預覽工具列按鈕無法正常更新啟用/停用狀態。

解決方案:在 CMyPreviewView::OnDraw(CDC* pDC) 繪製結尾補發訊息:

// 方案一
m_pToolBar->OnUpdateCmdUI((CFrameWnd*)AfxGetApp()->m_pMainWnd, TRUE);
// 方案二
m_pToolBar->PostMessage(WM_IDLEUPDATECMDUI, (WPARAM)TRUE);

每次視圖重繪即主動觸發命令 UI 更新,確保工具列、狀態列狀態即時同步。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved