📄 formctrl.cpp
字号:
/*****************************************************************************
File: FormControl.cpp
Purpose:
Implement the CFormControl class from which the Form OLE Controls can be
derived. The primary purpose of this class is to create the controls
window using CWnd::CreateDlg. Also provided is a default design time
representation of the control, a means of forcing the control to the
size of the dialog template, and code to handle mouse and keyboard
processing.
Includes:
#include "FormControl.h"
#include "Wnd2.h"
#include "AfxPriv.h"
#include "AfxImpl.h"
#include "CtlImpl.h"
#include "OccImpl.h"
Functions:
CFormControl - Initialize member variables and calculate the dialog
template size.
OnSetExtent - Sets the size of the control.
OnInitialUpdate - Handles the child control initialization.
OnDraw - Provides a border at design time.
PreTranslateMessage - If m_hWnd is valid, allows IsDialogMessage to
to try and handle the message.
OnActivateControl - Handler to be executed when a child window gets the
focus.
OnSetFocus - Handles the case when tabbing into the OLE Form Control.
CreateControlWindow - Creates m_hWnd using CWnd::CreateDlg
SetOccDialogInfo - Copied from CFormView.
HandleInitDialog - Copied from CFormView
GetClassID - Had to override COleControl pure virtual function.
GetUserTypeNameID - Had to override COleControl pure virtual function.
GetMiscStatus - Had to override COleControl pure virtual function.
OnMouseActivate - To make the OLE control layer transparent mouse
OnMouseMove - messages should come through the child controls.
OnLButtonDblClk - These functions have empty implementations so as
OnLButtonDown - to turn off the default mouse message processing
OnLButtonUp - of an OLE control.
OnMButtonDblClk - See Above.
OnMButtonDown - See Above.
OnMButtonUp - See Above.
OnRButtonDblClk - See Above.
OnRButtonDown - See Above.
OnRButtonUp - See Above.
Other:
_AfxCheckDialogTemplate - Global helper function copied from CFormView.
Development Team: ShawnK
Written by Microsoft Product Support Services, Languages Developer Support
Copyright (c) 1993 Microsoft Corporation. All rights reserved.
\****************************************************************************/
#include "stdafx.h"
#include "FormCtrl.h"
#include "AfxPriv.h"
#include "AfxImpl.h"
#include "CtlImpl.h"
#include "OccImpl.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_DYNCREATE(CFormControl, COleControl)
//**************************************************************************
// Initialize member variables and calculate the dialog template size.
CFormControl::CFormControl(LPCTSTR lpszTemplateName, BOOL bAutoSize):
m_bAutoSize(bAutoSize),
m_lpszTemplateName(lpszTemplateName),
m_hWndCurrentChild(NULL),
m_cTemplateSize(0,0),
m_sFormName("Form Control")
{
// load dialog resource
LPDLGTEMPLATE lpDialogTemplate = NULL;
HGLOBAL hDialogTemplate = NULL;
HINSTANCE hInst = AfxFindResourceHandle(m_lpszTemplateName, RT_DIALOG);
HRSRC hResource = ::FindResource(hInst, m_lpszTemplateName, RT_DIALOG);
hDialogTemplate = LoadResource(hInst, hResource);
if (hDialogTemplate != NULL)
lpDialogTemplate = (LPDLGTEMPLATE)LockResource(hDialogTemplate);
ASSERT(lpDialogTemplate != NULL);
// Get the dialog template size in pixels for OnSetExtent.
CDialogTemplate cdt_Form(lpDialogTemplate);
tagSIZE dlgSize;
cdt_Form.GetSizeInPixels(&dlgSize);
m_cTemplateSize.cx = dlgSize.cx;
m_cTemplateSize.cy = dlgSize.cy;
// free dialog resource
UnlockResource(hDialogTemplate);
FreeResource(hDialogTemplate);
}
//**************************************************************************
// Initialize member variables and calculate the dialog template size.
CFormControl::CFormControl(UINT nIDTemplate, BOOL bAutoSize):
m_bAutoSize(bAutoSize),
m_hWndCurrentChild(NULL),
m_cTemplateSize(0,0),
m_sFormName("Form Control")
{
ASSERT_VALID_IDR(nIDTemplate);
m_lpszTemplateName = MAKEINTRESOURCE(nIDTemplate);
// load dialog resource
LPDLGTEMPLATE lpDialogTemplate = NULL;
HGLOBAL hDialogTemplate = NULL;
HINSTANCE hInst = AfxGetInstanceHandle();
HRSRC hResource = ::FindResource(hInst, m_lpszTemplateName, RT_DIALOG);
hDialogTemplate = LoadResource(hInst, hResource);
if (hDialogTemplate != NULL)
lpDialogTemplate = (LPDLGTEMPLATE)LockResource(hDialogTemplate);
ASSERT(lpDialogTemplate != NULL);
// Get the dialog template size in pixels for OnSetExtent.
CDialogTemplate cdt_Form(lpDialogTemplate);
tagSIZE dlgSize;
cdt_Form.GetSizeInPixels(&dlgSize);
m_cTemplateSize.cx = dlgSize.cx;
m_cTemplateSize.cy = dlgSize.cy;
// free dialog resource
UnlockResource(hDialogTemplate);
FreeResource(hDialogTemplate);
}
//**************************************************************************
CFormControl::~CFormControl()
{
}
//**************************************************************************
// Set the size of the control to the size of the dialog template it was
// created from. This functionality can be turned off.
BOOL CFormControl::OnSetExtent( LPSIZEL lpSizeL )
{
if (m_bAutoSize) {
// This function limits the height of a control to
// to the size of the dialog template
// Use the desktop window to get a DC so we can use
// CDC::HIMETRICtoDP and CDC::DPtoHIMETRIC
CWnd *pWnd = CWnd::FromHandle(::GetDesktopWindow());
CClientDC dc(pWnd);
CSize sz(m_cTemplateSize.cx,m_cTemplateSize.cy);
dc.DPtoHIMETRIC(&sz);//re-convert to HIMETRIC
lpSizeL->cx = sz.cx;
lpSizeL->cy = sz.cy;
}
return COleControl::OnSetExtent(lpSizeL);
}
//**************************************************************************
// Modify CreateControlWindow to create m_hWnd using CreateDlg. This will
// create the window using the dialog resource parameter in the constructor.
BOOL CFormControl::CreateControlWindow(HWND hWndParent, const CRect& rcPos,
LPCRECT prcClipped)
{
ASSERT(hWndParent != NULL);
ASSERT(m_lpszTemplateName != NULL);
// If m_hWnd is NULL then call OnInitialUpdate.
BOOL bInitialUpdate = (m_hWnd == NULL);
if (prcClipped == NULL)
prcClipped = &rcPos;
if (m_hWnd == NULL)
{
// If window doesn't exist, create it.
// Test if:
// we're not subclassing a Windows control, or
// container reflects messages for us...
// we create normally if:
// (we're not subclassing -or- the container reflects)
// -and- the container autoclips for us
if ((!IsSubclassedControl() || m_bMsgReflect) && m_bAutoClip)
{
// Just create the control's window.
#ifdef _DEBUG
// dialog template must exist and be invisible with WS_CHILD set
if (!_AfxCheckDialogTemplate(m_lpszTemplateName, TRUE))
{
ASSERT(FALSE); // invalid dialog template name
PostNcDestroy(); // cleanup if Create fails too soon
return FALSE;
}
#endif //_DEBUG
#ifdef _MAC
HINSTANCE hInst = AfxFindResourceHandle(m_lpszTemplateName, RT_DIALOG);
_AfxStripDialogCaption(hInst, m_lpszTemplateName);
#endif
// initialize common controls
if (AfxDeferRegisterClass(AFX_WNDOLECONTROL_REG))
{
// create a modeless dialog window.
CWnd* pParent = CWnd:: FromHandle(hWndParent);
if (!CreateDlg(m_lpszTemplateName, pParent))
return FALSE;
if (m_hWnd != NULL) {
MoveWindow (rcPos, TRUE);
::ShowWindow(hWndParent, SW_SHOW);
::ShowWindow(m_hWnd, SW_SHOW);
SetFocus();
}
}
}
else // ...we're subclassing a Windows control.
{
if (m_pReflect == NULL)
{
// Create a window to reflect notification messages.
m_pReflect = new CReflectorWnd;
if (!m_pReflect->Create(prcClipped, hWndParent))
{
// If m_pReflect->Create failed, then m_pReflect deleted itself.
m_pReflect = NULL;
}
}
else
{
// Reflector window already exists... just reparent it.
if (m_pReflect->m_hWnd != NULL)
{
::SetParent(m_pReflect->m_hWnd, hWndParent);
::SetWindowPos(m_pReflect->m_hWnd, NULL, 0, 0, 0, 0,
SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|
SWP_SHOWWINDOW);
}
}
if (m_pReflect != NULL && m_pReflect->m_hWnd != NULL)
{
#ifdef _DEBUG
// dialog template must exist and be invisible with WS_CHILD set
if (!_AfxCheckDialogTemplate(m_lpszTemplateName, TRUE))
{
ASSERT(FALSE); // invalid dialog template name
PostNcDestroy(); // cleanup if Create fails too soon
return FALSE;
}
#endif //_DEBUG
#ifdef _MAC
HINSTANCE hInst = AfxFindResourceHandle(m_lpszTemplateName, RT_DIALOG);
_AfxStripDialogCaption(hInst, m_lpszTemplateName);
#endif
// Create the control's window.
CreateDlg(m_lpszTemplateName, m_pReflect);
if (m_hWnd == NULL)
{
// Window creation failed: cleanup.
m_pReflect->DestroyWindow();
m_pReflect = NULL;
}else{
// Make both windows visible.
m_pReflect->ShowWindow(SW_SHOW);
MoveWindow (rcPos, TRUE);
::ShowWindow(m_hWnd, SW_SHOW);
SetFocus();
}
}
}
// Set the new window's font.
OnFontChanged();
}
else
{
// If window does exist, reparent and reposition it.
CWnd* pWndOuter = GetOuterWindow();
ASSERT(pWndOuter != NULL);
if (::GetParent(pWndOuter->m_hWnd) != hWndParent)
ReparentControlWindow(pWndOuter->m_hWnd, hWndParent);
::SetWindowPos(pWndOuter->m_hWnd, NULL, 0, 0, 0, 0,
SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|
SWP_SHOWWINDOW);
if (m_pReflect == NULL)
::MoveWindow(m_hWnd, rcPos.left, rcPos.top,
rcPos.Width(), rcPos.Height(), TRUE);
else
{
pWndOuter->MoveWindow(prcClipped, TRUE);
::MoveWindow(m_hWnd, m_ptOffset.x, m_ptOffset.y,
rcPos.Width(), rcPos.Height(), TRUE);
}
}
ASSERT(m_hWnd != NULL);
// Send message to overridable OnInitialUpdate.
if (bInitialUpdate) {
InitControlContainer();
UpdateData(FALSE);
PostMessage(WM_INITIALUPDATE, 0, 0);
}
return (m_hWnd != NULL);
}
//**************************************************************************
// Diagnostic routine to check for and decode dialog templates returns FALSE
// if a program error occurs (i.e. bad resource ID or bad dialog styles).
// Copied from MFC.
BOOL AFXAPI _AfxCheckDialogTemplate(LPCTSTR lpszResource, BOOL bInvisibleChild)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -