読者です 読者をやめる 読者になる 読者になる

Objective-C + WindowsAPIを使ってCreateWindow

クラス化は適当。

MFApplication.h

#import <windows.h>
#import <objc/Object.h>


@interface MFApplication: Object
{
  HINSTANCE HInstance;
}
-(HINSTANCE)HInstance;
-(void)setHInstance:(HINSTANCE)AHInstance;
-(void)run;
@end

MFApplication.m

#import "MFApplication.h"
#import <stdio.h>

static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK CreateWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);


@implementation MFApplication
-(LRESULT)WindowProc:(HWND)hWnd MSG:(UINT) msg WPARAM:(WPARAM) wparam lPARAM:(LPARAM) lparam
{
  switch (msg)
    {
    case WM_PAINT:
      break;
    case WM_DESTROY:
      PostQuitMessage(0);
      break;
    }
  return DefWindowProc(hWnd, msg, wparam, lparam);
}

-(HINSTANCE)HInstance
{
  return self->HInstance;
}

-(void)setHInstance:(HINSTANCE)AHInstance
{
  self->HInstance = AHInstance;
}

-(void)run
{
  WNDCLASSEX wc;
  HWND hWnd;
  MSG msg;

  wc.cbSize        = sizeof(WNDCLASSEX);
  wc.style         = CS_HREDRAW | CS_VREDRAW;
  wc.lpfnWndProc   = CreateWndProc;
  wc.cbClsExtra     = 0;
  wc.cbWndExtra     = 0;
  wc.lpszClassName = "MFApplication";
  wc.hInstance     = self->HInstance;
  wc.hIcon          = LoadIcon(NULL, IDI_APPLICATION);
  wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  wc.hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);
  wc.lpszMenuName   = NULL;
  wc.hIconSm        = NULL;

  if (RegisterClassEx(&wc))
    {
      hWnd = CreateWindowEx(WS_EX_ACCEPTFILES,
                            wc.lpszClassName,
                            "Form Caption",
                            WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                            CW_USEDEFAULT,
                            CW_USEDEFAULT,
                            640,
                            480,
                            NULL,
                            NULL,
                            wc.hInstance,
                            self);

      ShowWindow(hWnd, SW_SHOWNORMAL);
      UpdateWindow(hWnd);

      while (GetMessage(&msg, NULL, 0, 0) != 0)
        {
          TranslateMessage(&msg);
          DispatchMessage (&msg);
        }
    }
}

@end

//wndproc

LRESULT CALLBACK
WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  id this = (MFApplication*)(GetWindowLongPtr(hWnd,
                                              GWL_USERDATA));
  if (this)
    {
      return [this WindowProc: hWnd MSG:msg WPARAM: wParam lPARAM: lParam];
    }

  return 0;
}

LRESULT CALLBACK
CreateWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  if (msg == WM_CREATE)
    {
      id this = (MFApplication*)(((LPCREATESTRUCT)lParam)->lpCreateParams);
      if (this)
        {
          SetWindowLongPtr(hWnd, GWL_USERDATA, (LONG_PTR)this);
          SetWindowLongPtr(hWnd, GWL_WNDPROC, (LONG_PTR)WndProc);

          return [this WindowProc:hWnd MSG:msg WPARAM:wParam lPARAM: lParam];
        }
    }

  return DefWindowProc(hWnd, msg, wParam, lParam);
}

main.m

#import <windows.h>
#import "MFApplication.h"


int WINAPI
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
  id app = [MFApplication new];

  [app setHInstance: hInstance];

  [app run];

  [app free];

  return 0;
}

MinGWgccで、-mwindowsとか -lobjcとか付けてmakeすればWindowが表示される。