我似乎無法找到這在msdn上搜索了一下(如下所述)。我個人的個人MFC
請原諒我貼的代碼量,我會按順序粘貼。你真的可以跳過大部分。但我只是想把它放在那裏,所以我的要求很明確。
可以說我想做一個非常簡單的MFC。所以我有以下抽象和具體的類(粘貼在下面),我想在我真正蹩腳的框架。
我還假設(雖然尚未實現)WinMain將調用用戶定義的主函數(如Qt)。我需要做什麼以便我可以在我嘗試編寫的其他小型蹩腳Win32程序中重複使用我的代碼。爲了更清楚,我想知道我是否將它編譯成DLL或庫。如果是的話,我該如何去做這件事?如何在DLL中包含WinMain函數?
#ifndef IAPPLICATION_H_
#define IAPPLICATION_H_
#include <Windows.h>
namespace nApplication
{
class IController;
class IWindow;
class IApplication
{
public:
virtual int Run() = 0;
virtual HINSTANCE gethInstance() = 0;
virtual int getnCmdShow() = 0;
virtual IController* getMainControl() = 0;
protected:
IWindow *main_window;
IController *main_control;
private:
virtual int MessageLoop() = 0;
};
}
#endif /* IAPPLICATION */
-
#ifndef APPLICATION_H_
#define APPLICATION_H_
#include <Windows.h>
#include "IApplication.h"
#include "IWindow.h"
#include "IController.h"
#include "Controller.h"
namespace nApplication
{
class Application : public IApplication
{
public:
Application(HINSTANCE hInstance, int nCmdShow);
virtual ~Application();
virtual int Run();
virtual int getnCmdShow() { return mnCmdShow; }
virtual HINSTANCE gethInstance() { return mhInstance; }
virtual IController* getMainControl() { return main_control; }
private:
int mnCmdShow;
HINSTANCE mhInstance;
int MessageLoop();
Application(Application &app);
Application& operator= (const Application &app);
};
}
#endif /* IAPPLICATION */
-
#include "Application.h"
#include "MainWindow.h"
namespace nApplication
{
Application::Application(HINSTANCE hInstance, int nCmdShow)
: mhInstance(hInstance), mnCmdShow(nCmdShow)
{
}
Application::~Application()
{
}
int Application::Run()
{
main_window = new MainWindow(this);
main_control = new Controller(this);
main_window->Init();
main_window->Display();
MessageLoop();
delete main_window;
return 0;
}
int Application::MessageLoop()
{
MSG msg;
while(GetMessage(&msg, NULL, 0, 0) != 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
}
-
#ifndef IWINDOW_H_
#define IWINDOW_H_
#include <Windows.h>
#include "IController.h"
namespace nApplication
{
class IWindow
{
public:
virtual void Init() = 0;
virtual void Display() = 0;
private:
};
}
#endif /* IWINDOW_H_ */
-
#ifndef MAINWINDOW_H_
#define MAINWINDOW_H_
#include <windows.h>
#include "IWindow.h"
#include "IController.h"
#include "IApplication.h"
namespace nApplication
{
class MainWindow : public IWindow
{
public:
MainWindow(IApplication *iApp);
~MainWindow();
void Init();
void Display();
private:
WNDCLASSEX wc;
HWND hWnd;
IApplication *iApp;
};
}
#endif //MAINWINDOW_H_
-
#include "MainWindow.h"
namespace nApplication
{
namespace
{
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hDC;
PAINTSTRUCT ps;
static IController *cntrl;
cntrl = (IController*)::GetWindowLongPtr(hWnd, GWL_USERDATA);
if(uMsg == WM_NCCREATE)
{
cntrl = (IController*)(((CREATESTRUCT*)lParam)->lpCreateParams);
::SetWindowLongPtr(hWnd, GWL_USERDATA, (LONG_PTR)cntrl);
cntrl->CheckStatus();
return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
}
switch(uMsg)
{
case WM_CREATE:
{
}
case WM_PAINT:
{
hDC = BeginPaint(hWnd, &ps);
TextOut(hDC, 10, 10, TEXT("Hello, Windows!"), 15);
EndPaint(hWnd, &ps);
return 0;
}
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
default:
{
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
}
}
}
MainWindow::MainWindow(IApplication* iApp) : iApp(iApp)
{
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = iApp->gethInstance();
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = TEXT("GenericAppMenu");
wc.lpszClassName = TEXT("myWindowClass");
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
}
MainWindow::~MainWindow()
{
}
void MainWindow::Init()
{
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, TEXT("Window Registration Failed!"), TEXT("Error!"), MB_ICONEXCLAMATION | MB_OK);
exit(0);
}
}
void MainWindow::Display()
{
hWnd = ::CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("myWindowClass"),
TEXT("The title of my window"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
240, 120, NULL, NULL, iApp->gethInstance(), iApp->getMainControl());
if(hWnd == NULL)
{
::MessageBox(NULL, TEXT("Window Creation Failed!"),
TEXT("Error!"), MB_ICONEXCLAMATION | MB_OK);
exit(0);
}
::ShowWindow(hWnd, iApp->getnCmdShow());
::UpdateWindow(hWnd);
}
}
-
#ifndef ICONTROLLER_H_
#define ICONTROLLER_H_
#include <windows.h>
namespace nApplication
{
class IController
{
public:
virtual int CheckStatus() = 0;
};
}
#endif ICONTROLLER_H_
-
#ifndef CONTROLLER_H_
#define CONTROLLER_H_
#include <windows.h>
#include "IController.h"
#include "IApplication.h"
namespace nApplication
{
class Controller : public IController
{
public:
Controller(IApplication *iApp);
virtual ~Controller();
virtual int CheckStatus();
private:
Controller(Controller &c);
Controller& operator= (Controller &c);
IApplication *iApp;
};
}
#endif //CONTROLLER_H_
-
#include "Controller.h"
namespace nApplication
{
Controller::Controller(IApplication *iApp) : iApp(iApp)
{
}
Controller::~Controller()
{
}
int Controller::CheckStatus()
{
return 0;
}
}
-
#include <windows.h>
#include "Application.h"
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
nApplication::Application app(hInstance, nCmdShow);
return app.Run();
}
-
main.exe : main.cpp
cl /EHsc main.cpp Application.cpp Controller.cpp MainWindow.cpp user32.lib gdi32.lib
del *.obj
#/link /SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup
我在Qt表單上有兩個線程來解決這個問題,那裏的成員說通過鏈接到類似於MFC的Qts DLL「包含」了WinMain。例如,請參閱http://developer.qt.nokia.com/forums/viewthread/8908/#51775最後幾篇文章。在我通過源代碼工作時,我仍然有點困惑。這是我正在嘗試理解的第一個開源項目。這是我做我所做事情的主要動機。 –
@Matthew:Qt的工作原理與多平臺用戶界面dev有所不同:它使用'main'作爲程序入口點(在你的代碼中),但在widows上它會創建自己的僞「WinMain」 (儘管它實際上不需要,但它只需要確保沒有控制檯被創建,如果沒有請求) – Necrolis
我現在有兩個相互衝突的解釋。我知道#/ link/SUBSYSTEM:WINDOWS/ENTRY:nmake Makefile中的mainCRTStartup允許你在非控制檯應用程序中指定入口點爲main()。但是,當你設置你的WndClassEx時,你需要一個hInstance,如果你使用main,這個hInstance是不提供的。沒有其他方法可以創建窗口。另外,如果你在Qt中查看源代碼,你會發現WinMain實際上調用了你的主函數。所以main不是程序的入口點,它只是非Windows程序員的習慣。這不是在linux中被稱爲條目。 –