src/msw/windows.cpp
まあ、もはやお決まり。まず、src/[platform]/window.cppをみる、のだ。これであなたも俺様window systemにwxWidgetをportできますねw。
WM_PAINT
しかしまぁごてごてしているなぁ。
// Can be called from an application's OnPaint handler
void wxWindowMSW::OnPaint(wxPaintEvent& event)
{
#ifdef __WXUNIVERSAL__
event.Skip();
#else
HDC hDC = (HDC) wxPaintDCImpl::FindDCInCache((wxWindow*) event.GetEventObject());
if (hDC != 0)
{
MSWDefWindowProc(WM_PAINT, (WPARAM) hDC, 0);
}
#endif
}
一見入り組んでいるが、
- HandleEraseBkgndがM$ windows側から呼ばれるEventHandler。
- OnEraseBackgroundがwxのデフォルトのPaintEventHandler
bool wxWindowMSW::HandleEraseBkgnd(WXHDC hdc)
{
wxDCTemp dc(hdc, GetClientSize());
wxDCTempImpl *impl = (wxDCTempImpl*) dc.GetImpl();
impl->SetHDC(hdc);
impl->SetWindow((wxWindow *)this);
wxEraseEvent event(m_windowId, &dc);
event.SetEventObject(this);
bool rc = HandleWindowEvent(event);
// must be called manually as ~wxDC doesn't do anything for wxDCTemp
impl->SelectOldObjects(hdc);
return rc;
}
void wxWindowMSW::OnEraseBackground(wxEraseEvent& event)
{
// standard non top level controls (i.e. except the dialogs) always erase
// their background themselves in HandleCtlColor() or have some control-
// specific ways to set the colours (common controls)
if ( IsOfStandardClass() && !IsTopLevel() )
{
event.Skip();
return;
}
if ( GetBackgroundStyle() == wxBG_STYLE_CUSTOM )
{
// don't skip the event here, custom background means that the app
// is drawing it itself in its OnPaint(), so don't draw it at all
// now to avoid flicker
return;
}
wxDC *dc = event.GetDC();
if (!dc) return;
wxMSWDCImpl *impl = (wxMSWDCImpl*) dc->GetImpl();
// do default background painting
if ( !DoEraseBackground(GetHdcOf(*impl)) )
{
// let the system paint the background
event.Skip();
}
}
bool wxWindowMSW::DoEraseBackground(WXHDC hDC)
{
HBRUSH hbr = (HBRUSH)MSWGetBgBrush(hDC);
if ( !hbr )
return false;
wxFillRect(GetHwnd(), (HDC)hDC, hbr);
return true;
}
- RedrawWindowウィンドウのクライアント領域にある、指定された長方形またはリージョンを更新します
- InvalidateRect指定されたウィンドウの更新リージョンに 1 個の長方形を追加します。更新リージョンとは、ウィンドウのクライアント領域のうち、再描画しなければならない部分のことです。
う~~ん。ほかのプラットフォームは1つの関数なのに。M$は混乱しているなぁ。わけわからん。しかもフラグがすごくいっぱいあるし。こんなAPIを使わないといけないプログラマは気の毒だ。まあ歴史があるともいうが。
void wxWindowMSW::Refresh(bool eraseBack, const wxRect *rect)
{
HWND hWnd = GetHwnd();
if ( hWnd )
{
RECT mswRect;
const RECT *pRect;
if ( rect )
{
wxCopyRectToRECT(*rect, mswRect);
pRect = &mswRect;
}
else
{
pRect = NULL;
}
// RedrawWindow not available on SmartPhone or eVC++ 3
#if !defined(__SMARTPHONE__) && !(defined(_WIN32_WCE) && _WIN32_WCE < 400)
UINT flags = RDW_INVALIDATE | RDW_ALLCHILDREN;
if ( eraseBack )
flags |= RDW_ERASE;
::RedrawWindow(hWnd, pRect, NULL, flags);
#else
::InvalidateRect(hWnd, pRect, eraseBack);
#endif
}
}
UpdateWindow
ですね。
void wxWindowMSW::Update()
{
if ( !::UpdateWindow(GetHwnd()) )
{
wxLogLastError(_T("UpdateWindow"));
}
#if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
// just calling UpdateWindow() is not enough, what we did in our WM_PAINT
// handler needs to be really drawn right now
(void)::GdiFlush();
#endif // __WIN32__
}
0 件のコメント:
コメントを投稿