Eclipse で C++ (その3)

次に Makefile プロジェクトを変更する。

プロジェクトの変更

basic1.cpp を test.cpp にリネーム。
Makefile の basic1 を test に変更し、 ターゲットを test.exe に変更する。
Eclipse からビルド・実行してみる。
エラーが出る場合、Eclipse を一旦再起動してみる。
これで自分用の雛形が出来た。

プロジェクトのインポート

"Eclipseプロジェクトのインポート" で検索すると、いくつか記事が出て来るが、 結構面倒くさそうである。そこでもっと簡単な方法にした。

これまで通りプロジェクトを作成。 Makefile とソースを雛形のものと入れ替える。 これでとりあえず問題なさそうである。

Windows プログラム

粂井康孝さんのサイト( 猫でもわかるプログラミング )に Windows SDK編 第1部 というのがある。
ここの第1章から第4章のサンプルをコピペしてソースを用意した。
また、簡単なリソース スクリプトファイル testw.rc を用意した。

その次に Windows 用に Makefile を変更してビルドした。

Makefile の変更点

Makefile
DEBUG=1
#PTR32=1

OBJS =	testw.o resfilew.o

LIBS =

# リンカーオプション
LDFLAGS = -mwindows

TARGET =	testw.exe 

CXXFLAGS = -Wall -fmessage-length=0 
#CXXFLAGS += -UNICODE 

ifeq ($(DEBUG),1)
CXXFLAGS += -O0 -g  -D_DEBUG
LDFLAGS +=  -Wl,--subsystem,console
else
CXXFLAGS += -Os   
endif

ifeq ($(PTR32),1)
CXXFLAGS +=   -D__PTR32
endif

#出力を Shift_JIS にする
#CXXFLAGS += -fexec-charset=CP932


$(TARGET):	$(OBJS)
	$(CXX) -o $(TARGET) $(OBJS) $(LDFLAGS) $(LIBS)

all:	$(TARGET)

resfilew.o: testw.rc
	windres -c 65001  -o resfilew.o testw.rc

clean:
	del *.o
	del *.exe

主な変更点はリンカーオプションである。

後、windres によりリソーススクリプトをリソースに変換している。

文字コード

残念ながら、元のソースをUTF-8 に直したものは、そのままではコンパイルできない。
Windows API は Shift_JIS の文字列を受付けるものと、 UTF-16 の UNCODE を受付けるものの二種類が用意されているが、 UTF8 を受付ける API は用意されていないためである。 そこで以下のように修正した。

ソースの頭に #define UNICODE を置く (コンパイルオプションで -DUNCODE でもよい)。
これで UTF-16 用の API が呼ばれるようになる。
次に UTF8 の文字列をUTF16 の文字列に変換してからAPIに渡す。

testw.cpp

//    sample01.cpp
#define UNICODE
#include 

#ifdef _DEBUG    
#include 
#endif

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInst,
                   LPSTR lpszCmdLine, int nCmdShow)
{
    HWND hWnd;
    MSG msg;
    WNDCLASS myProg;
    wchar_t szClassNme[100];
    wchar_t szMenuName[100];
    wchar_t szTitle[100];

//*** UTF-8 の文字列を UTF-16 に変換
   MultiByteToWideChar(CP_UTF8, 0, "ウィンドウクラス・ネーム", -1, szClassNme, 100);
   MultiByteToWideChar(CP_UTF8, 0, "MainMenu", -1, szMenuName, 100);
   MultiByteToWideChar(CP_UTF8, 0, "猫でもわかるプログラミング", -1, szTitle, 100);

#ifdef _DEBUG    
printf("** デバッグ1 **\n");
fputs("** デバッグ2 **",stderr);
#endif
    
    if (!hPreInst) {
        myProg.style            =CS_HREDRAW | CS_VREDRAW;
        myProg.lpfnWndProc      =WndProc;
        myProg.cbClsExtra       =0;
        myProg.cbWndExtra       =0;
        myProg.hInstance        =hInstance;
        myProg.hIcon            =NULL;
        myProg.hCursor          =LoadCursor(NULL, IDC_ARROW);
        myProg.hbrBackground    =(HBRUSH)GetStockObject(WHITE_BRUSH);
        myProg.lpszMenuName     =szMenuName;
        myProg.lpszClassName    =szClassNme;
        if (!RegisterClass(&myProg))
            return FALSE;
    }
    
    hWnd = CreateWindow(szClassNme,
        szTitle,
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL);
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return (msg.wParam);
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg) {
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return(DefWindowProc(hWnd, msg, wParam, lParam));
    }
    return (0L);
}

testw.rc (リソーススクリプト)

#include 

MainMenu MENU
BEGIN
	POPUP "&File"
	BEGIN
		MENUITEM "&New",1
		MENUITEM "&Open",2
		MENUITEM "&E&xit",3
	END

	POPUP "&Help"
	BEGIN
		MENUITEM "&About",4
		MENUITEM "てすと",5
	END
END


その2 その4   戻る