アプリケーションクラスの怪

[戻る]
すずも 2004/07/15(木) 00:47:20
 こんなクラス(↓)を作ってみたんです。

//〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

class CBaseApplication
{
protected:
    HWND    m_hWnd;

private:
    //ウィンドウプロージャを呼び出すためのバイパス。
    static CBaseApplication *m_lpInstance;

    static LRESULT CALLBACK    MsgProcInstance(HWND,UINT,WPARAM,LPARAM)
    {
        return m_lpInstance->MsgProc(HWND,UINT,WPARAM,LPARAM);
    }

public:
    bool InitApp(hInstance);    //初期化+m_lpInstanceの定義。

    virtual LRESULT MsgProc(HWND,UINT,WPARAM,LPARAM)
    {
        return DefWindowProc(HWND,UINT,WPARAM,LPARAM);
    }

    virtual int Run()
    { 
        //メッセージループ
    }
};

//〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

int main(HINSTANCE hInstance)
{
    CBaseApplication cApp;

    if(!cApp.InitApp(hInstance)) return 1;

    return cApp.Run();
}

//〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

 このクラス、特に問題なく動作するのは良いんですが、何故かアイドル時にマシンパ
ワーをやたらと喰うんです。タスクマネージャで見てみると常時CPU使用率100%。非アイ
ドル時は逆にCPU使用率が大きく下がるんですが...。
 これって何とかならないものなんでしょうか?


開発環境:
P C:Dell Dimension2400C
CPU:Celeron2.6GHz, 512MB
WindowsXP SP1, VC++ 6.0

monkey 2004/07/15(木) 07:20:27
> このクラス、特に問題なく動作する

省略部(InitApp,Runの定義)も問題に関係する可能性があります.
また,InitApp,Runの定義を補ったとしても,コンパイルできるものには見えません.
問題が再現される最小限のコードを書いてくれないと,何も分かりません.

すずも 2004/07/17(土) 00:23:19
 ちと端折りすぎましたか。すいません。
 問題が再現されるコード、一から書き直してみました。

//〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

#include <windows.h>

class CBaseApplication
{
protected:
    HWND    m_hWnd;

private:
    static CBaseApplication *m_lpInstance;
    static LRESULT CALLBACK MsgProcInstance(HWND hwnd,UINT uMsg,WPARAM 
wP,LPARAM lP);

public:
    virtual int Run(void);

    virtual bool InitApp(HINSTANCE hInst);
    virtual LRESULT MsgProc(HWND hwnd,UINT uMsg,WPARAM wP,LPARAM lP);
};

//〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

#include "CBaseApplication.h"

CBaseApplication *CBaseApplication::m_lpInstance = NULL;

bool CBaseApplication::InitApp(HINSTANCE hInst)
{
    WNDCLASS wc;

    m_lpInstance = this;

    ZeroMemory(&wc,sizeof(WNDCLASS));
    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wc.hCursor = LoadCursor(NULL,IDC_ARROW);
    wc.hInstance = hInst;
    wc.lpfnWndProc = MsgProcInstance;
    wc.lpszClassName = "CAppFrame";
    RegisterClass(&wc);

    // ウインドウを作成
    m_hWnd = CreateWindow("CAppFrame","CAppFrameTest", WS_VISIBLE | 
WS_OVERLAPPEDWINDOW,
            
    CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hIns
t,NULL);
    if(m_hWnd==NULL) return false;

    // 一旦ウィンドウを表示。
    ShowWindow( m_hWnd, SW_SHOWDEFAULT );
    UpdateWindow( m_hWnd );

    return true;
}

int CBaseApplication::Run()
{
    MSG msg;

    while(msg.message != WM_QUIT){
        if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)){
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return 0;
}

//メッセージ処理を呼び出すためのバイパス。
LRESULT CALLBACK CBaseApplication::MsgProcInstance(HWND hwnd,UINT uMsg,WPARAM 
wP,LPARAM lP)
{
    return m_lpInstance->MsgProc(hwnd,uMsg,wP,lP);
}

LRESULT CBaseApplication::MsgProc(HWND hwnd,UINT uMsg,WPARAM wP,LPARAM lP)
{
    switch(uMsg){
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    }

    return DefWindowProc(hwnd,uMsg,wP,lP);
}

//〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

#include "CBaseApplication.h"

int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int 
nCmdShow)
{
    CBaseApplication    cApp;

    if(!(cApp.InitApp(hInst))) return 1;

    return cApp.Run();
}

//〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

 以上です。もちろんこのままだと何の役にも立たないので実際に利用するときは基底ク
ラスとして必要なメンバを追加しますが、このままでも件の問題が生じます。
 それと、CPU使用率が上がっても他の作業には影響を与えないみたいです。では。

Peek 2004/07/17(土) 01:02:35
世の中に出回っているごく一般的なメッセージループの書き方と
自分のプログラムとの違いを比較してみてください。

#PeekMessage() は CPU に「お休みなさい」とは言ってくれません。

すずも 2004/07/18(日) 00:57:23
[[解決]]
PeekMessage(&msg,NULL,0,0,PM_REMOVE) → GetMessage(&msg, NULL, 0, 0)
 とすることで解決できました。ありがとうございます。

 メッセージループなんてコピペでいいや、って思っていたんですが、そうも行かなか
ったんですね...反省。

古いスレッドには追加発言できません。