void CXTPPropertyPage::OnChildSetFocus(HWND hWndFocus) { if ((GetStyle() & (WS_HSCROLL | WS_VSCROLL)) == 0) return; CWnd* pWnd = CWnd::FromHandle(hWndFocus); if (!pWnd) return; CRect rc; pWnd->GetWindowRect(rc); ScreenToClient(rc); CXTPClientRect rcClient(this); CSize szScroll(0, 0); if (rc.bottom > rcClient.bottom) szScroll.cy = rc.bottom - rcClient.bottom; if (rc.top - szScroll.cy < rcClient.top) szScroll.cy = rc.top - rcClient.top; if (rc.right > rcClient.right) szScroll.cx = rc.right - rcClient.right; if (rc.left - szScroll.cx < rcClient.left) szScroll.cx = rc.left - rcClient.left; if (szScroll != CSize(0, 0)) { OnScrollBy(szScroll, TRUE); } }
/** * ScrollByMoveY(const int dy) * ドラッグ中の描画処理 * 引数 * dy:マウスのY座標(point.y値、CTouchListCtrlコントロールのローカル座標、絶対値) * 戻り値 * 描画位置が先頭か最後尾になった場合にtrue、そうでない場合にfalseを返す * 関連するメンバ変数 * m_ptDragStart :(I) :ドラッグ開始点 * m_iItemHeight :(I) :アイテム1個当たりの高さ(ピクセル) * m_iDragLine :(I/O) :ドラッグ開始から現在までにスクロールした行数 * m_offsetPixelY :(O) :ピクセル単位スクロールのためのオフセット値 * 機能 * ・ドラッグ開始点(m_ptDragStart.y)からマウスの現在位置(dy)の移動量を基に * 画面に表示するItemの位置を決定し、スクロールして表示する */ bool CTouchListCtrl::ScrollByMoveY(const int dy) { util::StopWatch sw; sw.start(); // 先頭or最後尾フラグ bool bLimitOver = false; // 現時点での表示アイテム先頭位置、オフセットを保存する int iTop = GetTopIndex(); int iOffset = m_offsetPixelY; // Drag開始点からの移動行数を求める int iScrollLine = (( dy - m_ptDragStart.y ) / m_iItemHeight ) ; // ★ if (m_bBlackScrollMode) { // PIXEL単位でスクロールさせる m_offsetPixelY = -(( dy - m_ptDragStart.y ) % m_iItemHeight ); } else { #ifndef WINCE // PIXEL単位でスクロールさせる m_offsetPixelY = -(( dy - m_ptDragStart.y ) % m_iItemHeight ); #else if (theApp.m_optionMng.m_bListScrollByPixelOnMZ3) { // PIXEL単位でスクロールさせる m_offsetPixelY = -(( dy - m_ptDragStart.y ) % m_iItemHeight ); } else { // Item単位でスクロールさせる(WMデフォルト) m_offsetPixelY = 0; } #endif } // 前回の移動行数からの差分だけスクロールする // Scroll()メソッドはピクセル数指定だが、ピクセル指定すると // 1行分の半分くらいで1行移動したりしてマウスの動きと同期が取れないので // 行数×高さで動かす if( abs(iScrollLine - m_iDragLine) > 0 ){ CSize szScroll( 0 , -(( iScrollLine - m_iDragLine ) * m_iItemHeight) ); MZ3_TRACE( L" ScrollByMoveY, Scroll(%5d)\n" , szScroll.cy ); // Win32では独自処理で描画する // WMでは処理が追いつかないので標準処理に任せる // スクロール中の再描画を禁止 #ifndef WINCE LockWindowUpdate(); #endif // スクロール実行 Scroll( szScroll ); // スクロール中の再描画を再開 #ifndef WINCE UnlockWindowUpdate(); #endif } // スクロール後の先頭位置を取得する int iNextTop = GetTopIndex(); // 上端より上または下端より下ならばオフセットを効かせない if( ( iNextTop < 0 ) || ( iNextTop == 0 && m_offsetPixelY < 0) || ( GetItemCount() - GetCountPerPage() == iNextTop && m_offsetPixelY > 0) || ( GetItemCount() - GetCountPerPage() < iNextTop ) ){ m_offsetPixelY = 0; } if( ( iNextTop <= 0 ) || ( GetItemCount() - GetCountPerPage() <= iNextTop ) ){ // 先頭or最後尾フラグ bLimitOver = true; } bool bDoRedraw = false; if( iTop != iNextTop ) { // Item表示位置が変わった // トータル移動行数を蓄積する m_iDragLine += iTop - iNextTop; MZ3_TRACE( L" ScrollByMoveY, DrawBackSurface() req1\n" ); bDoRedraw = true; } else { // Item表示位置は変わらない if (iOffset != m_offsetPixelY) { // オフセットが変わった MZ3_TRACE( L" ScrollByMoveY, DrawBackSurface() req2\n" ); bDoRedraw = true; } } if (bDoRedraw) { if (m_bBlackScrollMode) { // 再描画 DrawBackSurface(); UpdateWindow(); } else { #ifndef WINCE // 再描画 // Win32では独自処理で描画する DrawBackSurface(); UpdateWindow(); #else if (theApp.m_optionMng.m_bListScrollByPixelOnMZ3) { // ピクセル単位スクロールの場合はWMでも独自処理で描画する DrawBackSurface(); UpdateWindow(); } #endif } } // MZ3LOGGER_INFO(util::FormatString(L" ScrollByMoveY elapsed : %dmsec", sw.getElapsedMilliSecUntilNow())); return bLimitOver; }