HelloIDD_HELLODIALOGCHelloDialog : public CDialogHelloCtrl.h 加入 #include "HelloDialog.h" 與成員 CHelloDialog m_helloDialog;void DoHello():
void CHelloCtrl::DoHello() { m_helloDialog.DoModal(); }
int CHelloCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) {
if (COleControl::OnCreate(lpCreateStruct) == -1) return -1;
m_helloDialog.Create(IDD_HELLODIALOG); // 建立非模態
return 0;
}
void CHelloCtrl::DoHello() { m_helloDialog.ShowWindow(SW_SHOW); }
對話框屬性設定:
int CHelloCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) {
if (COleControl::OnCreate(lpCreateStruct) == -1) return -1;
m_helloDialog.Create(IDD_HELLODIALOG, this); // 父視窗為控制項
return 0;
}
void CHelloCtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid) {
m_helloDialog.MoveWindow(rcBounds, TRUE); // 同步大小
}
IDD_HELLOFORMVIEW,屬性同 Child 模式CHelloFormView : public CFormViewHelloFormView.h:建構子/解構子改 public,加 friend class CHelloCtrl;HelloCtrl.h 成員 CHelloFormView m_helloFormView;
int CHelloCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) {
if (COleControl::OnCreate(lpCreateStruct) == -1) return -1;
m_helloFormView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
CRect(0,0,0,0), this, AFX_IDW_PANE_FIRST, NULL);
return 0;
}
void CHelloCtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid) {
m_helloFormView.MoveWindow(rcBounds, TRUE);
}
CPrintFrame : CFrameWnd, CPrintView : CView, CPrintDoc : CDocument, CPrintThread : CWinThreadpublicHelloCtrl.h 成員 CPrintThread* m_pPrintThread;
void CHelloCtrl::DoHello() {
m_pPrintThread = (CPrintThread*)AfxBeginThread(RUNTIME_CLASS(CPrintThread),
THREAD_PRIORITY_NORMAL, CREATE_SUSPENDED);
m_pPrintThread->ResumeThread();
}
// CPrintThread::InitInstance
BOOL CPrintThread::InitInstance() {
CPrintFrame* pFrame = new CPrintFrame;
m_pMainWnd = pFrame; m_pPrintFrame = pFrame;
m_pPrintDoc = new CPrintDoc;
CCreateContext ctx;
ctx.m_pCurrentDoc = m_pPrintDoc;
ctx.m_pNewViewClass = RUNTIME_CLASS(CPrintView);
pFrame->Create(NULL, _T("列印主視窗"), WS_OVERLAPPEDWINDOW,
CRect(0,0,100,100), NULL, NULL, 0, &ctx);
pFrame->InitialUpdateFrame(m_pPrintDoc, TRUE);
return TRUE;
}
// CPrintThread 建構/解構管理 Doc/Frame 生命週期
CPrintThread::CPrintThread() : m_pPrintDoc(NULL), m_pPrintFrame(NULL) {}
CPrintThread::~CPrintThread() {
if (m_pPrintFrame) delete m_pPrintFrame;
if (m_pPrintDoc) delete m_pPrintDoc;
}
CPrintView 覆寫 OnPreparePrinting:return DoPreparePrinting(pInfo);CHelloCtrl 加自動化方法 DoPreview()、SetPreviewControl()WM_USER_PREVIEW = WM_USER + 10
// CHelloCtrl
void CHelloCtrl::DoPreview() {
::PostMessage(m_pPrintThread->m_pPrintFrame->GetActiveView()->m_hWnd,
WM_USER_PREVIEW, 0, 0);
}
void CHelloCtrl::SetPreviewControl() {
CView* pView = m_pPrintThread->m_pPrintFrame->GetActiveView();
static_cast(pView)->m_pControlPreview = this;
}
// CPrintView
#define WM_USER_PREVIEW WM_USER + 10
BEGIN_MESSAGE_MAP(CPrintView, CView)
ON_MESSAGE(WM_USER_PREVIEW, DoPreview)
END_MESSAGE_MAP()
LRESULT CPrintView::DoPreview(WPARAM, LPARAM) {
OnFilePrintPreview(); return 0;
}
void CPrintView::OnDraw(CDC* pDC) {
if (!m_pControlPreview) { pDC->TextOut(0,0,_T("No Preview")); return; }
CRect cr; m_pControlPreview->GetClientRect(&cr);
m_pControlPreview->OnDraw(pDC, cr, cr);
}
DoHello() 建立列印執行緒SetPreviewControl() 綁定預覽來源DoPreview() 觸發預覽
ActiveX 控制項 (UI 執行緒)
│
├─ DoHello() → CPrintThread (UI 執行緒)
│ │
│ ├─ CPrintFrame (框架視窗)
│ │ └─ CPrintView (視圖)
│ │
│ └─ CPrintDoc (文件)
│
├─ SetPreviewControl() → CPrintView::m_pControlPreview = this
│
└─ DoPreview() → PostMessage → CPrintView::OnFilePrintPreview()
└─ OnDraw → m_pControlPreview->OnDraw()