|
|
1.1 root 1: // This is a part of the Microsoft Foundation Classes C++ library.
2: // Copyright (C) 1992 Microsoft Corporation
3: // All rights reserved.
4: //
5: // This source code is only intended as a supplement to the
6: // Microsoft Foundation Classes Reference and Microsoft
7: // QuickHelp documentation provided with the library.
8: // See these sources for detailed information regarding the
9: // Microsoft Foundation Classes product.
10:
11:
12: #include "afxwin.h"
13: #pragma hdrstop
14: #include "window_.h"
15:
16: #ifndef _NTWIN
17: #include "penwin.h" // MFC Apps are PenAware by default
18: #endif
19:
20: #ifdef AFX_CORE_SEG
21: #pragma code_seg(AFX_CORE_SEG)
22: #endif
23:
24: #ifdef _DEBUG
25: #include "trace_.h"
26: #undef THIS_FILE
27: static char BASED_CODE THIS_FILE[] = __FILE__;
28: #endif
29:
30: /////////////////////////////////////////////////////////////////////////////
31: // Define global state in ordinary "C" globals
32:
33: extern "C"
34: {
35: CWinApp* afxCurrentWinApp = NULL;
36: HANDLE afxCurrentInstanceHandle = NULL;
37: HANDLE afxCurrentResourceHandle = NULL;
38: const char* afxCurrentAppName = NULL;
39: }
40:
41: /////////////////////////////////////////////////////////////////////////////
42: // other globals (internal library use)
43:
44: // Proc addresses for Win3.1 specifics
45: #ifndef _WINDLL
46: HOOKPROC (WINAPI* _afxSetWindowsHookExProc)(int, HOOKPROC, HINSTANCE, HTASK);
47: static void (FAR PASCAL *_afxRegisterPenAppProc)(UINT, BOOL);
48: #endif //!_WINDLL
49:
50: /////////////////////////////////////////////////////////////////////////////
51:
52: IMPLEMENT_DYNAMIC(CWinApp, CObject)
53:
54: #ifdef _DEBUG
55: void CWinApp::AssertValid() const
56: {
57: CObject::AssertValid();
58: ASSERT(afxCurrentWinApp == this);
59: ASSERT(afxCurrentInstanceHandle == m_hInstance);
60: }
61:
62: void CWinApp::Dump(CDumpContext& dc) const
63: {
64: CObject::Dump(dc);
65: dc << "\nm_hInstance = " << (UINT)m_hInstance;
66: dc << "\nm_hPrevInstance = " << (UINT)m_hPrevInstance;
67: dc << "\nm_lpCmdLine = " << m_lpCmdLine;
68: dc << "\nm_nCmdShow = " << m_nCmdShow;
69: dc << "\nm_pMainWnd = " << m_pMainWnd;
70: }
71: #endif
72:
73: inline void CWinApp::SetCurrentHandles()
74: {
75: ASSERT(this == afxCurrentWinApp);
76: afxCurrentInstanceHandle = m_hInstance; // for instance tagging
77: afxCurrentResourceHandle = m_hInstance; // for resource loading
78:
79: if (m_pszAppName == NULL)
80: {
81: // get name/path of executable
82: char szName[256];
83: ::GetModuleFileName(m_hInstance, szName, sizeof(szName)-1);
84: m_pszAppName = _strdup(szName);
85: }
86: afxCurrentAppName = m_pszAppName;
87: ASSERT(afxCurrentAppName != NULL);
88: }
89:
90: /////////////////////////////////////////////////////////////////////////////
91:
92: CWinApp::CWinApp(const char* pszAppName)
93: {
94: m_pszAppName = pszAppName;
95: // in non-running state until WinMain
96: m_hInstance = NULL;
97: m_pMainWnd = NULL;
98:
99: ASSERT(afxCurrentWinApp == NULL); // only one CWinApp object please
100: afxCurrentWinApp = this; // hook for WinMain
101:
102: #ifdef _DEBUG
103: m_nDisablePumpCount = 0;
104: #endif
105: }
106:
107: #ifdef _DEBUG
108: void CWinApp::EnablePump(BOOL bEnable)
109: {
110: if (bEnable)
111: m_nDisablePumpCount--;
112: else
113: m_nDisablePumpCount++;
114: ASSERT(m_nDisablePumpCount >= 0);
115: }
116: #endif // _DEBUG
117:
118:
119: BOOL CWinApp::PumpMessage()
120: {
121: #ifdef _DEBUG
122: if (m_nDisablePumpCount != 0)
123: {
124: TRACE("Error: CWinApp::PumpMessage() called when not permitted\n");
125: ASSERT(FALSE);
126: }
127: #endif
128:
129: if (!::GetMessage(&m_msgCur, NULL, NULL, NULL))
130: {
131: #ifdef _DEBUG
132: if (afxTraceFlags & 2)
133: TRACE("PumpMessage - Received WM_QUIT\n");
134: m_nDisablePumpCount++; // application must die
135: // NOTE: prevents calling message loop things in 'ExitInstance'
136: // will never be decremented
137: #endif
138: return FALSE;
139: }
140:
141: #ifdef _DEBUG
142: if (afxTraceFlags & 2)
143: AfxTraceMsg("PumpMessage", &m_msgCur);
144: #endif
145:
146: // process this message
147: if (!PreTranslateMessage(&m_msgCur))
148: {
149: ::TranslateMessage(&m_msgCur);
150: ::DispatchMessage(&m_msgCur);
151: }
152: return TRUE;
153: }
154:
155: int CWinApp::Run()
156: {
157: /* Acquire and dispatch messages until a WM_QUIT message is received. */
158:
159: while (1)
160: {
161: LONG lIdleCount = 0;
162: // check to see if we can do idle work
163: while (!::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE) &&
164: OnIdle(lIdleCount++))
165: {
166: // more work to do
167: }
168:
169: // either we have a message, or OnIdle returned false
170:
171: if (!PumpMessage())
172: break;
173: }
174:
175: return ExitInstance();
176: }
177:
178: /////////////////////////////////////////////////////////////////////////////
179: // Stubs for standard initialization
180:
181: BOOL CWinApp::InitApplication()
182: {
183: return TRUE;
184: }
185:
186: BOOL CWinApp::InitInstance()
187: {
188: return TRUE;
189: }
190:
191: /////////////////////////////////////////////////////////////////////////////
192: // Stubs for standard implementation
193:
194: BOOL CWinApp::PreTranslateMessage(MSG* pMsg)
195: {
196: register HWND hWnd;
197: register CWnd* pWnd;
198:
199: // walk from the target window up to the desktop window seeing
200: // if any window wants to translate this message
201: for (hWnd = pMsg->hwnd; hWnd != NULL; hWnd = ::GetParent(hWnd))
202: {
203: if ((pWnd = CWnd::FromHandlePermanent(hWnd)) != NULL)
204: {
205: // target window is a C++ window
206: if (pWnd->PreTranslateMessage(pMsg))
207: return TRUE; // trapped by target window (eg: accelerators)
208:
209: if (pWnd == m_pMainWnd)
210: return FALSE; // got to our main window without interest
211: }
212: }
213:
214: // in case of modeless dialogs, last chance route through main window's
215: // accelerator table
216: if (m_pMainWnd != NULL && m_pMainWnd->PreTranslateMessage(pMsg))
217: return TRUE; // trapped by main window (eg: accelerators)
218:
219: return FALSE; // no special processing
220: }
221:
222:
223: BOOL CWinApp::OnIdle(LONG /*lCount*/)
224: {
225: CGdiObject::DeleteTempMap();
226: CDC::DeleteTempMap();
227: CMenu::DeleteTempMap();
228: CWnd::DeleteTempMap();
229: return FALSE; // no more processing (sleep please)
230: }
231:
232: int CWinApp::ExitInstance()
233: {
234: return m_msgCur.wParam; // Returns the value from PostQuitMessage
235: }
236:
237: /////////////////////////////////////////////////////////////////////////////
238: // Standard init called by WinMain
239:
240: static BOOL NEAR RegisterWithIcon(register WNDCLASS* pWndCls,
241: const char* szClassName, UINT nIDIcon)
242: {
243: pWndCls->lpszClassName = szClassName;
244: if ((pWndCls->hIcon = ::LoadIcon(pWndCls->hInstance,
245: MAKEINTRESOURCE(nIDIcon))) == NULL)
246: {
247: // use default icon
248: pWndCls->hIcon = ::LoadIcon(NULL, IDI_APPLICATION);
249: }
250: return RegisterClass(pWndCls);
251: }
252:
253: /////////////////////////////////////////////////////////////////////////////
254:
255: extern "C"
256: BOOL AfxWinInit(HINSTANCE hInstance, HINSTANCE hPrevInstance,
257: LPSTR lpCmdLine, int nCmdShow)
258: {
259: register CWinApp* pApp = AfxGetApp();
260:
261: ASSERT(pApp != NULL); // must have one
262:
263: // fill in the initial state for the application
264: pApp->m_hInstance = hInstance;
265: pApp->m_hPrevInstance = hPrevInstance;
266: pApp->m_lpCmdLine = lpCmdLine;
267: pApp->m_nCmdShow = nCmdShow;
268: pApp->SetCurrentHandles();
269:
270: // Windows version specific initialization
271: #ifndef _WINDLL
272: WORD wVersion = LOWORD(::GetVersion());
273: if (LOBYTE(wVersion) > 3 || HIBYTE(wVersion) >= 10)
274: {
275: #ifndef _NTWIN
276: HINSTANCE hPenWin;
277: if ((hPenWin = (HINSTANCE)GetSystemMetrics(SM_PENWINDOWS)) != NULL)
278: {
279: static char BASED_CODE szRegisterPenApp[] = "RegisterPenApp";
280: _afxRegisterPenAppProc = (void (WINAPI*)(UINT, BOOL))
281: ::GetProcAddress(hPenWin, szRegisterPenApp);
282: if (_afxRegisterPenAppProc != NULL)
283: (*_afxRegisterPenAppProc)(RPA_DEFAULT, TRUE);
284: }
285: #endif //!_NTWIN
286:
287: // Windows 3.1 or better - use SetWindowsHookEx (USER.291)
288: static char BASED_CODE szUSER[] = "USER";
289: _afxSetWindowsHookExProc =
290: (HOOKPROC (WINAPI*)(int, HOOKPROC, HINSTANCE, HTASK))
291: ::GetProcAddress(::GetModuleHandle(szUSER), MAKEINTRESOURCE(291));
292: }
293: #endif //!_WINDLL
294:
295: if (hPrevInstance == NULL) // one instance initialization
296: {
297: // register basic WndClasses
298: WNDCLASS wndcls;
299: memset(&wndcls, 0, sizeof(WNDCLASS)); // start with NULL defaults
300:
301: // common initialization
302: wndcls.lpfnWndProc = AfxWndProc;
303: wndcls.hInstance = hInstance;
304: wndcls.hCursor = ::LoadCursor(NULL, IDC_ARROW);
305: wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
306:
307: // Child windows - no brush, no icon
308: wndcls.lpszClassName = _afxWnd;
309: if (!::RegisterClass(&wndcls))
310: return FALSE;
311:
312: // MDI Frame windows
313: if (!RegisterWithIcon(&wndcls, _afxMDIFrameWnd, AFX_IDI_STD_MDIFRAME))
314: return FALSE;
315:
316: // SDI Frame or MDI Child windows - normal colors
317: wndcls.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
318: if (!RegisterWithIcon(&wndcls, _afxFrameWnd, AFX_IDI_STD_FRAME))
319: return FALSE;
320: }
321:
322: return TRUE;
323: }
324:
325: extern "C"
326: void AfxWinTerm(void)
327: {
328: // These static CWnd objects refer to HWNDs that don't exist
329: // so let's not call ::DestroyWindow when CWnd::~CWnd() is invoked.
330: ((CWnd&)CWnd::wndTop).m_hWnd = NULL;
331: ((CWnd&)CWnd::wndBottom).m_hWnd = NULL;
332: ((CWnd&)CWnd::wndTopMost).m_hWnd = NULL;
333: ((CWnd&)CWnd::wndNoTopMost).m_hWnd = NULL;
334:
335: #ifndef _WINDLL
336: #ifndef _NTWIN
337: // if we registered ourself with PenWin, deregister now
338: if (_afxRegisterPenAppProc != NULL)
339: (*_afxRegisterPenAppProc)(RPA_DEFAULT, FALSE);
340: #endif //!_NTWIN
341: #endif //!_WINDLL
342: }
343:
344: /////////////////////////////////////////////////////////////////////////////
345: // force WinMain or LibMain inclusion
346:
347: #ifdef _WINDLL
348: extern "C" int PASCAL LibMain(HINSTANCE, WORD, WORD, LPSTR);
349: static FARPROC linkAddr = (FARPROC) &LibMain;
350: #else
351: extern "C" int PASCAL WinMain(HINSTANCE, HINSTANCE, LPSTR, int);
352: static FARPROC linkAddr = (FARPROC) &WinMain;
353: #endif //!_WINDLL
354:
355: /////////////////////////////////////////////////////////////////////////////
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.