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