プログラミングメモ →目次

楕円形ウィンドウ(VC++)

int SetWindowRgn( 
    HWND hWnd,    // handle to window whose window region is to be set
    HRGN hRgn,    // handle to region
    BOOL bRedraw  // window redraw flag
);

という関数だけで、楕円形のウィンドウを作ることができます。テストプログラムとして、楕円状のウィンドウ上に、ボタンを貼り付けて、一秒の間隔のタイマーを作成して、このタイマーで電子時計のように時刻をボタンの上に表示させます。

1.CWndの派生クラスCEllipseWndを作成します。
2.楕円形のリージョンを作成します。
3.楕円形のリージョンをCEllipseWndから生成された実体に設定します。
4.ボタンを作成します。
5.タイマーを作成します。

#define ELLIPSE_WIDTH 200
#define ELLIPSE_HEIGHT 150
#define IDC_BUTTON1    1001

/////////////////////////////////////////////////////////////////////////////
// CEllipseWnd

CEllipseWnd::CEllipseWnd()
{
    CString strClassName 
        = AfxRegisterWndClass(NULL, 
                              theApp.LoadStandardCursor(IDC_CROSS),
                              (HBRUSH)::GetStockObject(LTGRAY_BRUSH));
    CreateEx(0, 
             strClassName, 
             "Ellipse Window",
             WS_POPUP,
             CW_USEDEFAULT, 
             CW_USEDEFAULT, 
             CW_USEDEFAULT, 
             CW_USEDEFAULT,
             NULL, 
             NULL, 
             NULL);

    SetWindowPos(NULL, 
                 0, 
                 0, 
                 ELLIPSE_WIDTH,
                 ELLIPSE_HEIGHT,
                 SWP_NOZORDER | SWP_NOMOVE | SWP_NOREDRAW);

    HRGN hRgn = CreateEllipticRgn(0, 
                                  0, 
                                  ELLIPSE_WIDTH - 1, 
                                  ELLIPSE_HEIGHT - 1);
    SetWindowRgn(hRgn, TRUE);
 
    DeleteObject(hRgn);
    m_btnClock.Create("00:00:00",  WS_CHILD | WS_VISIBLE,
                      CRect(ELLIPSE_WIDTH / 2 - 60, 
                            ELLIPSE_HEIGHT / 2 - 20, 
                            ELLIPSE_WIDTH / 2 + 60 ,
                            ELLIPSE_HEIGHT / 2 + 20),
                      this, IDC_BUTTON1);

    SetTimer(1, 1000, NULL);
    CenterWindow();
}

CEllipseWnd::~CEllipseWnd()
{
}


BEGIN_MESSAGE_MAP(CEllipseWnd, CWnd)
    //{{AFX_MSG_MAP(CEllipseWnd)
    ON_WM_NCHITTEST()
    ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
    ON_WM_TIMER()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CEllipseWnd メッセージ ハンドラ

UINT CEllipseWnd::OnNcHitTest(CPoint point) 
{
    return HTCAPTION;
}

void CEllipseWnd::OnButton1()
{
    SendMessage(WM_CLOSE);
}

void CEllipseWnd::OnTimer(UINT nIDEvent) 
{
    CTime tm = CTime::GetCurrentTime();
    CString strText;
    strText.Format("%02d:%02d:%02d", tm.GetHour(), tm.GetMinute(), tm.GetSecond());
    m_btnClock.SetWindowText(strText);
    CWnd::OnTimer(nIDEvent);
}

6.普通にCWinAppの派生クラスを作成します。InitInstance()関数の中で、CEllipseWndの実体を作成して、ウィンドウを立ち上げます。

BOOL CEllipseAppliApp::InitInstance()
{
    m_pMainWnd = new CEllipseWnd();
    m_pMainWnd->ShowWindow(m_nCmdShow);
    m_pMainWnd->UpdateWindow();
    return TRUE;
}