|
|
///////////////////////////////////////////////////////////
//
//
// SIZEBAR.cpp - CSizeBar control encapsulates the sizebar
//
//
//
// Copyright (C) 1996-1997 Microsoft Corporation. All rights reserved.
///////////////////////////////////////////////////////////
//
// Includes
//
#include "header.h"
#ifdef _DEBUG
#undef THIS_FILE
static const char THIS_FILE[] = __FILE__; #endif
#include "system.h"
#include "secwin.h"
#include "contain.h"
// For ID_TAB_CONTROL
#include "resource.h"
#include "windowsx.h"
// For the ScreenRectToClientRect Function.
#include "navpane.h"
///////////////////////////////////////////////////////////
//
// external functions.
//
///////////////////////////////////////////////////////////
//
// Constructor
//
CSizeBar::CSizeBar() : m_hWnd(NULL), m_hWndParent(NULL), m_pWinType(NULL), m_bDragging(false) {
}
///////////////////////////////////////////////////////////
//
// Destructor
//
CSizeBar::~CSizeBar() { if ( IsValidWindow(m_hWnd) ) { DestroyWindow( m_hWnd); } }
///////////////////////////////////////////////////////////
//
// Operations
///////////////////////////////////////////////////////////
//
// Create
//
bool CSizeBar::Create(CHHWinType* pWinType) { // Validate
ASSERT(pWinType) ; ASSERT(IsValidWindow(pWinType->GetHwnd())) ;
// Save
m_hWndParent = pWinType->GetHwnd(); m_pWinType = pWinType ;
// Calc the size
RECT rcSizeBar ; CalcSize(&rcSizeBar) ;
// Create the window.
m_hWnd = CreateWindow(txtSizeBarChildWindowClass, NULL, WS_CHILD | WS_VISIBLE, rcSizeBar.left, rcSizeBar.top, RECT_WIDTH(rcSizeBar), RECT_HEIGHT(rcSizeBar), m_hWndParent, NULL, _Module.GetModuleInstance(), NULL);
if (m_hWnd) { // Set the userdata to our this pointer.
SetWindowLongPtr(m_hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
return true; } else return false ; }
///////////////////////////////////////////////////////////
//
// ResizeWindow
void CSizeBar::ResizeWindow() { // Validate
ASSERT(IsValidWindow(hWnd())) ;
// Calculate our size.
RECT rc; CalcSize(&rc); // This will be the navigation window.
// Size the window.
MoveWindow(hWnd(), rc.left, rc.top, RECT_WIDTH(rc), RECT_HEIGHT(rc), TRUE); // need to repaint the sizebar when their is a margin on the right
// end of the toolbar so the ghost of the sizebar is removed
// Redraw the sizebar.
Draw() ; }
///////////////////////////////////////////////////////////
//
// RegisterWindowClass
//
void CSizeBar::RegisterWindowClass() { WNDCLASS wc;
ZeroMemory(&wc, sizeof(WNDCLASS)); // clear all members
wc.hInstance = _Module.GetModuleInstance(); wc.hbrBackground = (HBRUSH) COLOR_WINDOW; //wc.lpszMenuName = MAKEINTRESOURCE(HH_MENU);
wc.lpfnWndProc = s_SizeBarProc; wc.lpszClassName = txtSizeBarChildWindowClass; wc.hCursor = LoadCursor(NULL, IDC_SIZEWE);
VERIFY(RegisterClass(&wc)); }
///////////////////////////////////////////////////////////
//
// Access Functions
//
///////////////////////////////////////////////////////////
//
// Width
//
int CSizeBar::Width() { // Current the width is fixed, but based on metrics.
return GetSystemMetrics(SM_CXSIZEFRAME);
} ///////////////////////////////////////////////////////////
//
// Internal Helper Functions
//
///////////////////////////////////////////////////////////
//
// CalcSize
//
void CSizeBar::CalcSize(RECT* prect) { ASSERT(m_pWinType) ;
// Get the size of the HTML Help window.
RECT rectHtml ; ::GetWindowRect(m_pWinType->GetHTMLHwnd(), &rectHtml );
// Convert to the coordinates of help window itself.
ScreenRectToClientRect(m_hWndParent, &rectHtml) ;
// Now use this information to create our rectangle.
prect->left = rectHtml.left - Width() ; prect->right = prect->left + Width() ; prect->top = rectHtml.top ; prect->bottom = rectHtml.bottom ; }
///////////////////////////////////////////////////////////
//
// Draw
//
void CSizeBar::Draw() { // Get a dc to draw in.
HDC hdc = GetDC(hWnd()) ; // get the rectangle to draw on.
RECT rc ; GetClientRect(hWnd(), &rc) ;
// Draw the edge.
DrawEdge(hdc, &rc, EDGE_ETCHED, m_bDragging ? (BF_TOPLEFT | BF_BOTTOMRIGHT | BF_MIDDLE) :(BF_TOPLEFT | BF_BOTTOM | BF_MIDDLE)) ; // Clean up.
ReleaseDC(hWnd(), hdc) ;
}
///////////////////////////////////////////////////////////
//
// Member function Window Proc
//
LRESULT CSizeBar::SizeBarProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) {
case WM_LBUTTONDOWN: if ( wParam == MK_LBUTTON && m_pWinType) { SetCapture(hwnd); // capture the mouse to this window.
m_offset = GET_X_LPARAM(lParam) ; // The initial x position happens to be the offset.
m_bDragging = true ; } break; case WM_LBUTTONUP: if (m_bDragging && (GetCapture() == hwnd)) { ReleaseCapture(); // release the mouse capture from this window.
//TODO - This nasty code uses to many internal members of CHHWinType...
// Get the rectangle for the sizebar.
RECT rcSizeBar ; GetWindowRect(m_hWnd, &rcSizeBar) ; ScreenRectToClientRect(m_pWinType->GetHwnd(), &rcSizeBar) ;
// Change the left size of the Topic pane.
m_pWinType->rcHTML.left = rcSizeBar.right;
// move the Nav Pane
ASSERT(m_pWinType->GetNavigationHwnd()); if (m_pWinType->IsExpandedNavPane() && IsValidWindow(m_pWinType->hwndNavigation)) { m_pWinType->rcNav.right = rcSizeBar.left; } // resize the tab control and its' dialogs. This will also resize the sizebar and draw it.
::ResizeWindow(m_pWinType, false); // This is the one defined in wndproc.cpp. Don't recalc the sizes. Use the ones we've set.
m_bDragging = false ; }
break;
case WM_MOUSEMOVE: if (m_bDragging) { ASSERT(m_pWinType) ; // Get the rectangle for the htmlhelp window.
RECT rcHelpWin; GetClientRect(m_pWinType->GetHwnd(), &rcHelpWin);
// Get the rectangle for the sizebar.
RECT rcSizeBar ; GetWindowRect(m_hWnd, &rcSizeBar) ;
// Calculate the new position.
ScreenRectToClientRect(m_pWinType->GetHwnd(), &rcSizeBar) ; rcSizeBar.left += GET_X_LPARAM(lParam) - m_offset ; // The width of rcSizeBar is now not correct.
// Validate the new position.
if ( (rcSizeBar.left > MinimumPaneWidth()) && // Check left side.
(rcSizeBar.left + Width() < rcHelpWin.right - MinimumTopicWidth()) ) // Check right boundary.
{ // Move it.
SetWindowPos(m_hWnd, NULL, rcSizeBar.left, rcSizeBar.top, 0,0, SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER) ; } } break; case WM_PAINT: {
// Draw an edige on the left side of the size bar.
PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps) ; Draw() ; EndPaint(hwnd, &ps) ;
} break ; case WM_ERASEBKGND: return 1; // We don't want the background erased.
default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0; }
///////////////////////////////////////////////////////////
//
// Callbacks
//
///////////////////////////////////////////////////////////
//
// Static Window Proc
//
LRESULT WINAPI CSizeBar::s_SizeBarProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { CSizeBar* pThis = reinterpret_cast<CSizeBar*>(GetWindowLongPtr(hwnd, GWLP_USERDATA)); if (pThis) return pThis->SizeBarProc(hwnd, msg, wParam, lParam) ; else return DefWindowProc(hwnd, msg, wParam, lParam); }
|