CreateWindow関数でエラー

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
Cr
記事: 93
登録日時: 9年前

CreateWindow関数でエラー

#1

投稿記事 by Cr » 8年前

猫でもわかるc++というサイトでWindowプログラミングを学び始めて二日です。
とりあえずひな形の書き方に慣れるためにコンパイルして実行しようとしたのですがコピペでエラーが出ました…
ソースコード

コード:

//        timer.cpp

#include <Windows.h>
#include "timer.h"

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL InitApp(HINSTANCE, LPCSTR);
BOOL InitInstance(HINSTANCE, LPCSTR, int);

int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst,
                   LPSTR lpsCmdLine, int nCmdShow)
{
    MSG msg;
    char szClassName[] = "timer";        //ウィンドウクラス
    
    if (!hPrevInst) {
        if (!InitApp(hCurInst, szClassName))
            return FALSE;
    }
    if (!InitInstance(hCurInst, szClassName, nCmdShow)) {
        return FALSE;
    }
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}

//ウィンドウ・クラスの登録 BOOLはTRUEかFALSEしか返さないの意味

BOOL InitApp(HINSTANCE hInst, LPCSTR szClassName)
{
    WNDCLASS wc;
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WndProc;    //プロシージャ名
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInst;        //インスタンス
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName = (LPCWSTR)"TIMERMENU";    //メニュー名
    wc.lpszClassName = (LPCWSTR)szClassName;
    return (RegisterClass(&wc));
}

//ウィンドウの生成

BOOL InitInstance(HINSTANCE hInst, LPCSTR szClassName, int nCmdShow)
{
    HWND hWnd;

	hWnd = CreateWindow(szClassName,
		"timer",   //タイトルバーにこの名前が表示されます
            WS_OVERLAPPEDWINDOW,    //ウィンドウの種類
            CW_USEDEFAULT,    //X座標
            CW_USEDEFAULT,    //Y座標
            CW_USEDEFAULT,    //幅
            CW_USEDEFAULT,    //高さ
            NULL,            //親ウィンドウのハンドル、親を作るときはNULL
            NULL,            //メニューハンドル、クラスメニューを使うときはNULL
            hInst,            //インスタンスハンドル
            NULL);
    if (!hWnd)
        return FALSE;
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
    return TRUE;
}

//ウィンドウプロシージャ

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
    switch (msg) {
        case WM_COMMAND:    //メニューが選択されました
            switch (LOWORD(wp)) {
                case IDM_END:    //「終了」が選択されました。
                    SendMessage(hWnd, WM_CLOSE, 0, 0L);
                    break;
                default:
                    break;
            }
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:    //自分で処理しないメッセージはシステムに任せる
            return (DefWindowProc(hWnd, msg, wp, lp));
    }
    return 0L;
}

コード:

//    timer.rc

#include <windows.h>;
#include "timer.h"

//////////////////////////////////////////
//
// Menu
//

TIMERMENU MENU DISCARDABLE 
BEGIN
    MENUITEM "終了",                        IDM_END
END

コード:

// timer.h

#define IDM_END 1000
#define ID_MYTIMER 32767 

エラーメッセージは

コード:

error C2664: 'CreateWindowExW' : 2 番目の引数を 'LPCSTR' から 'LPCWSTR' に変換できません。行:64 列:1
エディタはMicrosoft VisualC++ 2010 Expressです。

beatle
記事: 1280
登録日時: 9年前
住所: 埼玉
連絡を取る:

Re: WindowCreate関数でエラー

#2

投稿記事 by beatle » 8年前

UNICODEモードになっているんじゃないでしょうか。UNICODEモードでは、TCHARはwchar_tとなりまして、これはcharとはサイズが異なります。当然、文字列は文字の配列であるために、wchar_tの文字列とcharの文字列はまったく互換性がありません。

CreateWindow関数の第1, 2引数はLPCTSTRなので、UNICODEモードか否かにより const wchar_t* か const char* か、要するに L"hoge" を渡すか "hoge" を渡すかが変わります。

LPCSTR型のポインタ値をLPCWSTR型にキャストしている場面がありますが、恐らく不正なキャストです。

アバター
Cr
記事: 93
登録日時: 9年前

Re: CreateWindow関数でエラー

#3

投稿記事 by Cr » 8年前

beatle さんが書きました:UNICODEモードになっているんじゃないでしょうか。
その通りでした!マルチバイト文字に設定をかえたらコンパイルが通りました
beatle さんが書きました: LPCSTR型のポインタ値をLPCWSTR型にキャストしている場面がありますが、恐らく不正なキャストです。
この部分は確かとりあえずキャストしてしまえという安直な考えからやってしまいました。
設定を変更したら無しでも通りました。

もうひとつキャストを付け足した部分がありまして、
BOOL InitApp();内の

コード:

wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
の(HBRUSH)というのも付け足しました。
無いと

コード:

error C2440: '=' : 'HGDIOBJ' から 'HBRUSH' に変換できません。
というエラーが出てしまいます。
これはマルチバイトに設定を変更しても無いとエラーが起きてしまうのですが何が原因なのでしょうか?

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 10年前
住所: 東海地方
連絡を取る:

Re: CreateWindow関数でエラー

#4

投稿記事 by softya(ソフト屋) » 8年前

キャストに関しては十分調べてから行った方が良いですね。

Win32APIの関数はMSDNでまず確認します。
「GetStockObject 関数」
http://msdn.microsoft.com/ja-jp/library/cc410411.aspx

説明に「定義済み(ストック)のペン、ブラシ、フォント、パレットのいずれかのハンドルを取得します。」とありますね。
幾通りかの型を戻り値で返すHGDIOBJは汎用型になっていますので使う場合はキャストして使うのが前提となっています。
これはマルチバイトに設定を変更しても無いとエラーが起きてしまうのですが何が原因なのでしょうか?
マルチバイトとUNICODEは文字コードの問題ですが、HBRUSHはブラシ型の問題ですから無関係で絶対しなければいけないキャストです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
Cr
記事: 93
登録日時: 9年前

Re: CreateWindow関数でエラー

#5

投稿記事 by Cr » 8年前

softya(ソフト屋) さんが書きました: 幾通りかの型を戻り値で返すHGDIOBJは汎用型になっていますので使う場合はキャストして使うのが前提となっています。
HGDIOBJとかHBRUSHとかってそういう意味だったんですね
まだ始めたばかりですので、教えていただいたサイトで色々調べながらやっていきたいと思います。
どうもありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る