ウィンドウクラス名を変更する

MFCでウィンドウを作成するとウィンドウクラス名が"Afx:400000:…"と
数字の羅列のウィンドウクラス名に勝手に決められてしまいます。
通常、ユーザはウィンドウクラス名を見る事は出来ませんので気にする事は有りませんが
FindWindow()を使ってウィンドウを探す場合、クラス名が決まっていると探しやすかったり
何かの都合で変更したい時が有るかもしれません。
そこでウィンドウクラス名の変更をしてやります。

まずはMFC AppWizardで作成したメインウィンドウのウィンドウクラス名の変更方法です。
MFC AppWizardで作成したアプリケーションは基本的にメインフレームがメインウィンドウになるので
メインフレームのウィンドウクラス名を変更してやります。
そこでPreCreateWindow()で以下のように記述してください。


BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
    if( !CFrameWnd::PreCreateWindow(cs) )
        return FALSE;
    // TODO: この位置で CREATESTRUCT cs を修正して、Window クラスやスタイルを
    //       修正してください。

    if (cs.lpszName)
    {
        WNDCLASS wc;
        ::GetClassInfo(AfxGetInstanceHandle(), cs.lpszClass, &wc);
        wc.lpszClassName = _T("test"); // 好きな名前を設定
        AfxRegisterClass(&wc);
        cs.lpszClass = wc.lpszClassName;
    }

    return TRUE;
}

ここで渡されるCREATESTRUCT構造体のlpszClassメンバを変更する事で
ウィンドウクラス名を変更する事が出来ます。
しかし、これに設定できるウィンドウクラス名はWindowsに登録された物でなければなりません。
そこで、GetClassInfo()で現在のウィンドウクラスの情報を取得し
ウィンドウクラス名だけ変更してAfxRegisterClass()で登録してやります。
その後、lpszClassを登録したウィンドウクラス名に変更してやってください。

それから最初に次のようにしてウィンドウキャプションが無いものを弾いているのは
> if (cs.lpszName)
基底クラスのCFrameWndクラスはウィンドウを作成する際
MFCが提供するウィンドウクラスでウィンドウを作成します。
その後、派生クラス(CMainFrame)でユーザのウィンドウを作成しているようですが
この時、2回PreCreateWindow()が呼ばれてしまいます。
最初に呼ばれた時は基底クラスのウィンドウクラス名が入っていて
これを変更してしまうとアイコンが変になるとかいった不具合が生じます。
これを回避する為に一時的なウィンドウにはウィンドウキャプションが無いのを利用し
ウィンドウクラス名を変更しないように弾いています。
# この辺の理屈はMFCのソースを読んで勝手に判断してるだけなので
# 間違ってる可能性は高いです。どなたかフォロー願います。(汗

このサンプルはドキュメントをサポートした場合のウィンドウクラス名の変更方法ですが
ドキュメントをサポートしていない場合も基本的には方法は同じです。
ただし以下の行は削除してください。
> cs.lpszClass = AfxRegisterWndClass(0);
# しかしこのコードはウィンドウクラス名を変更するしないにかかわらず削除した方が良いような・・・。

次は、CWnd::Create()等で新しくウィンドウを作成した場合の方法です。
この場合は最初にウィンドウクラスを登録してからウィンドウを作成したほうが良いでしょう。
以下にサンプルコードを記載します。


void CXxxDlg:CreateWindow() 
{
    // ウィンドウクラスの登録
    WNDCLASS wc = { 0 };
    wc.lpfnWndProc   = AfxWndProc;                           // 下記参照
    wc.hInstance     = AfxGetInstanceHandle();               // 現在のインスタンス
    wc.hCursor       = ::LoadCursor(NULL, IDC_ARROW);        // 標準のカーソル
    wc.style         = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW; // スタイル
    wc.lpszClassName = _T("test");                           // ウィンドウクラス名
    wc.hIcon         = NULL;                                 // 標準のアイコン
    wc.hbrBackground = NULL;                                 // ウィンドウの背景色
    AfxRegisterClass(&wc);

    // ウィンドウ表示
    CXxxWnd* pXxxWnd = new CXxxWnd;
    RECT rect = { 0, 0, 200, 150 };
    pXxxWnd->CreateEx(NULL, wc.lpszClassName, "TestWindow",
                   WS_OVERLAPPEDWINDOW | WS_VISIBLE, rect, this, 0);
}

基本的にはWNDCLASS構造体のメンバを自分で設定しウィンドウクラスを登録します。
ここで重要なのはWNDCLASS構造体のlpfnWndProcAfxWndProcを設定する事です。
MFCアプリケーションのウィンドウプロシージャはAfxWndProcになっていますので。
後は普通にメンバを設定してAfxRegisterClass()で登録すればOKです。
最後に登録されたウィンドウクラスでウィンドウを作成してください。

< 戻る << HOME ©1999-2001 by Akky, All right reserved.