/
ParentWnd.cpp
133 lines (116 loc) · 3.84 KB
/
ParentWnd.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// ParentWnd.cpp : implementation file
//
#include "stdafx.h"
#include "ParentWnd.h"
#include "ImportProcs.h"
#include "MyWinApp.h"
#include "NamedPropCache.h"
#include "UIFunctions.h"
extern CMyWinApp theApp;
static TCHAR* CLASS = _T("CParentWnd");
// This appears to be the only way to catch a column drag event
// Since we end up catching for EVERY event, we have to be clever to ensure only
// the CSingleMAPIPropListCtrl that generated it catches it.
// First, we throw WM_MFCMAPI_SAVECOLUMNORDERHEADER to whoever generated the event
// Most controls will ignore this - only CSortHeader knows this message
// That ditches most false hits
// Then CSortHeader throws WM_MFCMAPI_SAVECOLUMNORDERLIST to its parent
// Only CSingleMAPIPropListCtrl handles that, so we'll only get hits when the header for
// a particular CSingleMAPIPropListCtrl gets changed.
// We can't throw to the CSingleMAPIPropListCtrl directly since we don't have a handle here for it
void CALLBACK MyWinEventProc(
HWINEVENTHOOK /*hWinEventHook*/,
DWORD event,
_In_ HWND hwnd,
LONG /*idObject*/,
LONG /*idChild*/,
DWORD /*dwEventThread*/,
DWORD /*dwmsEventTime*/)
{
if (EVENT_OBJECT_REORDER == event)
{
HRESULT hRes = S_OK;
// We don't need to wait on the results - just post the message
WC_B(::PostMessage(
hwnd,
WM_MFCMAPI_SAVECOLUMNORDERHEADER,
(WPARAM) NULL,
(LPARAM) NULL));
}
} // MyWinEventProc
/////////////////////////////////////////////////////////////////////////////
// CParentWnd
CParentWnd::CParentWnd()
{
// OutputDebugStringOutput only at first
// Get any settings from the registry
SetDefaults();
ReadFromRegistry();
// After this call we may output to the debug file
OpenDebugFile();
DebugPrintVersion(DBGVersionBanner);
// Force the system riched20 so we don't load office's version.
(void) LoadFromSystemDir(_T("riched20.dll")); // STRING_OK
// Second part is to load rundll32.exe
// Don't plan on unloading this, so don't care about the return value
(void) LoadFromSystemDir(_T("rundll32.exe")); // STRING_OK
// Load DLLS and get functions from them
ImportProcs();
// Initialize objects for theming
InitializeGDI();
m_cRef = 1;
m_hwinEventHook = SetWinEventHook(
EVENT_OBJECT_REORDER,
EVENT_OBJECT_REORDER,
NULL,
&MyWinEventProc,
GetCurrentProcessId(),
NULL,
NULL);
ForceOutlookMAPI(0 != RegKeys[regkeyFORCEOUTLOOKMAPI].ulCurDWORD);
ForceSystemMAPI(0 != RegKeys[regkeyFORCESYSTEMMAPI].ulCurDWORD);
LoadAddIns();
// Notice we never create a window here!
TRACE_CONSTRUCTOR(CLASS);
} // CParentWnd::CParentWnd
CParentWnd::~CParentWnd()
{
// Since we didn't create a window, we can't call DestroyWindow to let MFC know we're done.
// We call AfxPostQuitMessage instead
TRACE_DESTRUCTOR(CLASS);
UninitializeGDI();
UnloadAddIns();
if (m_hwinEventHook) UnhookWinEvent(m_hwinEventHook);
UninitializeNamedPropCache();
WriteToRegistry();
CloseDebugFile();
// Since we're killing what m_pMainWnd points to here, we need to clear it
// Else MFC will try to route messages to it
theApp.m_pMainWnd = NULL;
AfxPostQuitMessage(0);
} // CParentWnd::~CParentWnd
_Check_return_ STDMETHODIMP CParentWnd::QueryInterface(REFIID riid,
_Deref_out_opt_ LPVOID * ppvObj)
{
*ppvObj = 0;
if (riid == IID_IUnknown)
{
*ppvObj = (LPVOID)this;
AddRef();
return S_OK;
}
return E_NOINTERFACE;
} // CParentWnd::QueryInterface
STDMETHODIMP_(ULONG) CParentWnd::AddRef()
{
LONG lCount = InterlockedIncrement(&m_cRef);
TRACE_ADDREF(CLASS,lCount);
return lCount;
} // CParentWnd::AddRef
STDMETHODIMP_(ULONG) CParentWnd::Release()
{
LONG lCount = InterlockedDecrement(&m_cRef);
TRACE_RELEASE(CLASS,lCount);
if (!lCount) delete this;
return lCount;
} // CParentWnd::Release