いまさらwindowsプログラミング
ちょっと気分転換で、windowsプログラミングを。
VC++ExpressEditionを使っています。
WinMain
#include <windows.h> int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int ) { return 0; }
これまでのようにcoutで出力できるように、コンソールを割り当てましょう。
#include <windows.h> #include <iostream> #define _CRTDBG_MAP_ALLOC #include <stdlib.h> #include <crtdbg.h> #define new ::new( _NORMAL_BLOCK, __FILE__, __LINE__ ) int main() { std::cout << "hoge" << std::endl; return 0; } int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int ) { //メモリリークの検出 _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); //コンソールの割り当て AllocConsole(); FILE* out = 0; freopen_s( &out, "CON", "w", stdout ); FILE* in = 0; freopen_s( &in, "CON", "r", stdin ); int ret = main(); getchar(); //コンソール解放 fclose( out ); fclose( in ); FreeConsole(); return ret; }
以降、int main()で処理を記述していきます。
main終了時にgetchar()を呼び出して停止しているので、必要なければ消してください。
ウィンドウの作成
ウィンドウの作り方はgoogle先生にお任せして、ここではすぐにクラス化していきます。
とりあえず、java風にしていきましょうか。
以下のように使用できるFrameクラスを作ります。
#include "System.h" #include "Frame.h" int main() { std::cout << "hoge" << std::endl; //デフォルトのプロシージャを使って、ウィンドウクラスの登録。 System::DefRegisterClass(); //ウィンドウの作成 Frame frame; frame.Create( 100, 100 ); //w, h System::MessageLoop(); return 0; }
System.h
#pragma once #include <windows.h> class System { private: static LRESULT CALLBACK WinProc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ); public: static bool DefRegisterClass(); static void MessageLoop(); };
System.cpp
#include "System.h" LRESULT CALLBACK System::WinProc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) { if( msg == WM_DESTROY ) { PostQuitMEssage( 0 ); return 0; } return DefWindowProc( hwnd, msg, wp, lp ); } bool System::DefRegisterClass() { WNDCLASSEX wc = { sizeof( WNDCLASSEX ), CS_HREDRAW | CS_VREDRAW, &System::WinProc, 0, 0, GetModuleHandle( 0 ), LoadIcon( 0, IDI_APPLICATION ), LoadCursor( 0, IDC_ARROW ), ( HBRUSH )GetStockObject( BLACK_BRUSH ), 0, "hoge", 0 }; if( !RegisterClassEx( &wc ) )return false; return true; } void System::MessageLoop() { MSG msg; while( GetMessage( &msg, 0, 0, 0 ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } }
ウィンドウクラス名は適当に"hoge"となっています。
Frame.h
#pragma once #include <windows.h> class Frame { private: HWND hwnd; public: Frame(); ~Frame(); public: bool Create( int w, int h ); };
Frame.cpp
#include "Frame.h" Frame::Frame() : hwnd( 0 ) { } Frame::~Frame(void) { } bool Frame::Create( int w, int h ) { hwnd = CreateWindowEx ( 0 , "hoge" , "title" , WS_OVERLAPPEDWINDOW , CW_USEDEFAULT , CW_USEDEFAULT , w , h , 0 , 0 , GetModuleHandle( 0 ) , this ); if( hwnd == 0 )return false; ShowWindow( hwnd, SW_SHOW ); return true; }
インスタンスハンドルはWinMainから渡してくるのが面倒だったので、GetModuleHandle( 0 )で取得しています。
次回はイベントを処理できるようにリスナを作っていきます。
自作functionを使っていきたいですね。