Improve error handling in Qt Mfc examples.
[qt-solutions:qt-solutions.git] / qtwinmigrate / examples / mfc / step2 / qtmfc.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the Qt Solutions component.
7 **
8 ** $QT_BEGIN_LICENSE:BSD$
9 ** You may use this file under the terms of the BSD license as follows:
10 **
11 ** "Redistribution and use in source and binary forms, with or without
12 ** modification, are permitted provided that the following conditions are
13 ** met:
14 **   * Redistributions of source code must retain the above copyright
15 **     notice, this list of conditions and the following disclaimer.
16 **   * Redistributions in binary form must reproduce the above copyright
17 **     notice, this list of conditions and the following disclaimer in
18 **     the documentation and/or other materials provided with the
19 **     distribution.
20 **   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
21 **     of its contributors may be used to endorse or promote products derived
22 **     from this software without specific prior written permission.
23 **
24 **
25 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
36 **
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40
41 // QtMfc.cpp : Defines the class behaviors for the application.
42 //
43
44 #include "stdafx.h"
45 #include "qtmfc.h"
46
47 #include "mainframe.h"
48 #include <string>
49 #include <sstream>
50
51 #include <qmfcapp.h>
52
53 #ifdef _DEBUG
54 #define new DEBUG_NEW
55 #undef THIS_FILE
56 static char THIS_FILE[] = __FILE__;
57 #endif
58
59 /////////////////////////////////////////////////////////////////////////////
60 // WindowsApp
61
62 BEGIN_MESSAGE_MAP(WindowsApp, CWinApp)
63         //{{AFX_MSG_MAP(WindowsApp)
64         ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
65         //}}AFX_MSG_MAP
66 END_MESSAGE_MAP()
67
68 /////////////////////////////////////////////////////////////////////////////
69 // WindowsApp construction
70
71 WindowsApp::WindowsApp()
72 {
73 }
74
75 /////////////////////////////////////////////////////////////////////////////
76 // The one and only WindowsApp object
77
78 WindowsApp theApp;
79
80 /////////////////////////////////////////////////////////////////////////////
81 // WindowsApp initialization
82
83 BOOL WindowsApp::InitInstance()
84 {
85         // Standard initialization
86
87 #if _MFC_VER < 0x0700
88 #ifdef _AFXDLL
89         Enable3dControls();                     // Call this when using MFC in a shared DLL
90 #else
91         Enable3dControlsStatic();       // Call this when linking to MFC statically
92 #endif
93 #endif
94
95         // Change the registry key under which our settings are stored.
96         SetRegistryKey(_T("Local AppWizard-Generated Applications"));
97
98
99
100         MainFrame* pFrame = new MainFrame;
101         m_pMainWnd = pFrame;
102
103         // create and load the frame with its resources
104
105         pFrame->LoadFrame(IDR_MAINFRAME,
106                 WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL,
107                 NULL);
108
109
110
111         pFrame->ShowWindow(SW_SHOW);
112         pFrame->UpdateWindow();
113
114         return TRUE;
115 }
116
117 BOOL WindowsApp::Run()
118 {
119     return QMfcApp::run( this );
120 }
121
122 /////////////////////////////////////////////////////////////////////////////
123 // WindowsApp message handlers
124
125
126
127
128
129 /////////////////////////////////////////////////////////////////////////////
130 // CAboutDlg dialog used for App About
131
132 class CAboutDlg : public CDialog
133 {
134 public:
135         CAboutDlg();
136
137 // Dialog Data
138         //{{AFX_DATA(CAboutDlg)
139         enum { IDD = IDD_ABOUTBOX };
140         //}}AFX_DATA
141
142         // ClassWizard generated virtual function overrides
143         //{{AFX_VIRTUAL(CAboutDlg)
144         protected:
145         virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
146         //}}AFX_VIRTUAL
147
148 // Implementation
149 protected:
150         //{{AFX_MSG(CAboutDlg)
151                 // No message handlers
152         //}}AFX_MSG
153         DECLARE_MESSAGE_MAP()
154 };
155
156 CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
157 {
158         //{{AFX_DATA_INIT(CAboutDlg)
159         //}}AFX_DATA_INIT
160 }
161
162 void CAboutDlg::DoDataExchange(CDataExchange* pDX)
163 {
164         CDialog::DoDataExchange(pDX);
165         //{{AFX_DATA_MAP(CAboutDlg)
166         //}}AFX_DATA_MAP
167 }
168
169 BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
170         //{{AFX_MSG_MAP(CAboutDlg)
171                 // No message handlers
172         //}}AFX_MSG_MAP
173 END_MESSAGE_MAP()
174
175 static inline void formatWindowsErrorMessage(DWORD errorCode, std::wostream &str)
176 {
177     wchar_t *string = 0;
178     FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
179                   NULL, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
180                   (LPWSTR)&string, 0, NULL);
181     if (string)
182         str << string;
183     else
184         str << "Unknown error";
185     LocalFree((HLOCAL)string);
186 }
187
188 static bool showQtAboutDialog(HWND parentWindow, std::wstring *errorMessage)
189 {
190     typedef BOOL(*pShowDialog)(HWND parent);
191
192     const char dllName[] = "qtdialog.dll";
193     const char functionName[] = "showDialog";
194
195     const HMODULE module = LoadLibraryA(dllName);
196     const DWORD errorCode = GetLastError();
197     if (!module) {
198         std::wostringstream str;
199         str << "Unable to load '" << dllName << "': Error #" << errorCode << ": ";
200         formatWindowsErrorMessage(errorCode, str);
201         *errorMessage = str.str();
202         return false;
203     }
204
205     pShowDialog showDialog = (pShowDialog)GetProcAddress(module, functionName);
206     if (!showDialog) {
207         std::wostringstream str;
208         str << "Unable to resolve function '" << functionName << "' in '"
209             << dllName << "'.";
210         *errorMessage = str.str();
211         return false;
212     }
213
214     showDialog(parentWindow);
215     FreeLibrary(module);
216     return true;
217 }
218
219 // App command to run the dialog
220 void WindowsApp::OnAppAbout()
221 {
222     const HWND parentWindow = theApp.m_pMainWnd->m_hWnd;
223     std::wstring errorMessage;
224     if (!showQtAboutDialog(parentWindow, &errorMessage)) {
225         MessageBoxW(parentWindow, errorMessage.c_str(), L"QtMfc 1.0 MFC Application",
226                     MB_OK | MB_ICONWARNING);
227     }
228 }
229
230 /////////////////////////////////////////////////////////////////////////////
231 // WindowsApp message handlers
232