// ************************************************************************ // MODULE : ToolBar.C // PURPOSE : // FUNCTIONS : // ************************************************************************ #define NOCREATEFONT #ifdef DEBUG #define DebugOut( str ) OutputDebugString ( (LPCTSTR) __FILE__ TEXT( ": " ) TEXT( str ) TEXT( "\n" ) ) #else #define DebugOut( str ) #endif #ifndef WIN32 #define INT int #endif #ifndef WIN32S #define UNICODE // make the application unicode complient #endif #define STRICT #include #include // For 'abs' #ifdef WIN32 #define GetWindowInstance(hwnd) (HANDLE) GetWindowLong( hwnd, GWL_HINSTANCE ) #define GetWindowID(hwnd) GetWindowLong( hwnd, GWL_ID ) #else #define GetWindowInstance(hwnd) (HANDLE) GetWindowWord( hwnd, GWW_HINSTANCE ) #define GetWindowID(hwnd) GetWindowWord( hwnd, GWW_ID ) #endif HWND hwndMain; HWND hwndTools, hwndToolText, hwndToolCombo, hwndToolButton; HWND hwndStatus; HFONT hfontTools=0; HFONT hfontStatus; TEXTMETRIC tmToolFont; TEXTMETRIC tmStatusFont; INT dyTools = 0, dyCombo; INT cxToolBorder, cyToolBorder, cntToolCtrls = 0; INT xCurrent = 10; INT dxTools; INT cntStatusField = 0; INT dyStatus, cxStatusBorder, cyStatusBorder, cxFrame, cyFrame, dyField; HBRUSH hbrBtnFace=0; HBRUSH hbrToolBar=0; HBRUSH hbrStatus=0; // HANDLE hInst=0; #define COLOR_BLACK RGB(0, 0, 0) #define COLOR_WHITE RGB(255, 255, 255) #define COLOR_HEAVYGRAY RGB(64, 64, 64) #define COLOR_DARKGRAY RGB(128, 128, 128) #define COLOR_GRAY RGB(192, 192, 192) COLORREF rgbFrame = COLOR_BLACK; COLORREF rgbBtnFace = COLOR_GRAY; COLORREF rgbHilite = COLOR_WHITE; COLORREF rgbDirectLight = COLOR_WHITE; COLORREF rgbShadow = COLOR_DARKGRAY; COLORREF rgbToolBar = COLOR_GRAY; COLORREF rgbStatic = COLOR_BLACK; #define TC_SPACE 0 #define TC_LABEL 1 #define TC_COMBO 2 #define TC_BUTTON 3 #define MAXCTRLS 25 typedef struct _tagTools { HWND hwnd; WORD wType; INT iWidth, iHeight; HICON hIcon; } Tools; Tools toolCtrl[MAXCTRLS]; #define MAXSTATUS 10 typedef struct _tagStatus { HWND hwnd; INT iMaxWidth, iMinWidth, iGiveWidth; } Status; Status statusField[ MAXSTATUS ]; //-- internal prototypes LONG CALLBACK ToolsProc (HWND, UINT, WPARAM, LPARAM); LONG CALLBACK MyComboProc (HWND, UINT, WPARAM, LPARAM); VOID UpdatePositions (HWND); LONG CALLBACK StatusProc (HWND, UINT, WPARAM, LPARAM); LONG CALLBACK StatusFieldProc (HWND, UINT, WPARAM, LPARAM); // ************************************************************************ // FUNCTION : DllEntryPoint( HINSTANCE, DWORD, LPVOID ) // PURPOSE : DllEntryPoint is called by Windows when // the DLL is initialized, Thread Attached, and other times. // COMMENTS : No initialization is needed here. // ************************************************************************ BOOL WINAPI DllEntryPoint( HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved ) { UNREFERENCED_PARAMETER( hInstDLL ); UNREFERENCED_PARAMETER( fdwReason ); UNREFERENCED_PARAMETER( lpvReserved ); return( TRUE ); } // ======================================================================== // TOOL BAR FUNCTIONS // ======================================================================== // ************************************************************************ // FUNCTION : InitToolBar (HANDLE hInstance) // PURPOSE : // COMMENTS : // ************************************************************************ BOOL InitToolBar (HANDLE hInstance) { WNDCLASS wndclass; hbrBtnFace = CreateSolidBrush( rgbBtnFace ); hbrToolBar = CreateSolidBrush( rgbToolBar ); wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = (WNDPROC) ToolsProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = NULL; wndclass.hbrBackground = hbrToolBar; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = TEXT( "ToolBar" ); if( !RegisterClass(&wndclass) ) return FALSE; } // ************************************************************************ // FUNCTION : CreateToolBar( HWND hwnd, HANDLE hInstance, INT iId ) // PURPOSE : // COMMENTS : // ************************************************************************ BOOL CreateToolBar( HWND hwnd, HANDLE hInstance, INT iId ) { HWND hwndTmp; RECT rect; DebugOut( "CreateToolBar" ); if( hbrBtnFace==0 ) hbrBtnFace = CreateSolidBrush( rgbBtnFace ); if( hbrToolBar==0 ) hbrToolBar = CreateSolidBrush( rgbToolBar ); cxToolBorder = GetSystemMetrics( SM_CXBORDER ); cyToolBorder = GetSystemMetrics( SM_CYBORDER ); DebugOut( "Calling CreateWindow" ); hwndTools = CreateWindow ( TEXT( "ToolBar" ), TEXT( "ToolBar" ), WS_CHILD | WS_CLIPSIBLINGS | WS_BORDER | WS_VISIBLE, 0, 0, 0, 0, hwnd, (HMENU) iId, hInstance, NULL ); if( !hwndTools ) { DebugOut( "CreateWindow Failed" ); return FALSE; } DebugOut( "CreateWindow suceeded" ); /* Lets find out how big a combo box is... */ hwndTmp = CreateWindow ( TEXT( "COMBOBOX" ), TEXT( "Combo" ), WS_CHILD //| WS_CLIPSIBLINGS | WS_VISIBLE | CBS_DROPDOWNLIST, 0, 0, 0, 0, hwndTools, NULL, hInstance, NULL); if( hwndTmp ) { // SendMessage( hwndTmp, WM_SETFONT, (UINT) hfontTools, MAKELONG (TRUE, 0) ); GetClientRect( hwndTmp, &rect ); dyCombo = rect.bottom - rect.top; DestroyWindow( hwndTmp ); } else { dyCombo = 30; // Just for a default value } hwndMain = hwnd; // So we can pass WM_CONTROL messages back to the master parent hInstance; // unreferenced return TRUE; } // ************************************************************************ // FUNCTION : ToolBarHeight( HWND hwnd ) // PURPOSE : // COMMENTS : // ************************************************************************ int ToolBarHeight( HWND hwnd ) { RECT rect; GetClientRect( hwndTools, &rect ); return( rect.bottom-rect.top ); hwnd; // unreferenced } // ************************************************************************ // FUNCTION : AdjustToolBar( HWND hwnd ) // PURPOSE : // COMMENTS : // ************************************************************************ BOOL AdjustToolBar( HWND hwnd ) { RECT rect; GetClientRect (hwnd, &rect); MoveWindow( hwndTools, rect.left - cxToolBorder, rect.top - cyToolBorder, rect.right - rect.left + (cxToolBorder*2), dyTools, TRUE ); return TRUE; } // ************************************************************************ // FUNCTION : UpdatePositions( HWND hwnd ) // PURPOSE : // COMMENTS : // ************************************************************************ VOID UpdatePositions( HWND hwnd ) { INT i, x, y, dx, dy, cnt; x = 10; for( i=0; i 5 ) cnt = 5; dy = dy * cnt; break; case TC_BUTTON: dy = toolCtrl[i].iHeight; y = (dyTools/2) - (dy/2) - 1; dx = toolCtrl[i].iWidth; break; default: dy = toolCtrl[i].iHeight; y = (dyTools/2) - (dy/2) - 1; dx = toolCtrl[i].iWidth; break; } if( toolCtrl[i].wType != TC_SPACE ) { MoveWindow( toolCtrl[i].hwnd, x, y, dx, dy, FALSE ); } x += dx; } if( hwnd == NULL ) { UpdateWindow( hwndTools ); } else{ UpdateWindow( hwnd ); } } // ************************************************************************ // FUNCTION : AddToolSpace( INT iWidth, INT iHeight ) // PURPOSE : // COMMENTS : // ************************************************************************ BOOL AddToolSpace( INT iWidth, INT iHeight ) { if( cntToolCtrls >= MAXCTRLS ) return FALSE; toolCtrl[cntToolCtrls].hwnd = 0; toolCtrl[cntToolCtrls].wType = TC_SPACE; toolCtrl[cntToolCtrls].iWidth = iWidth; toolCtrl[cntToolCtrls].iHeight = iHeight; if( (toolCtrl[cntToolCtrls].iHeight + (6*cyToolBorder)) > dyTools ) { dyTools = (toolCtrl[cntToolCtrls].iHeight + (6*cyToolBorder)); } UpdatePositions( NULL ); cntToolCtrls++; return( TRUE ); } // ************************************************************************ // FUNCTION : AddToolLabel( HANDLE hInst, INT iId, LPTSTR szLabel, INT iWidth, DWORD dwStyle ) // PURPOSE : // COMMENTS : // ************************************************************************ HWND AddToolLabel( HANDLE hInstance, INT iId, LPTSTR szLabel, INT iWidth, DWORD dwStyle ) { HDC hdc; if( cntToolCtrls >= MAXCTRLS ) return( (HWND) 0 ); // No room left in our fixed array toolCtrl[cntToolCtrls].hwnd = CreateWindow ( TEXT( "STATIC" ), szLabel, WS_CHILD //| WS_CLIPSIBLINGS | WS_VISIBLE | dwStyle, 0, 0, 0, 0, hwndTools, (HMENU)iId, hInstance, NULL ); if( !toolCtrl[cntToolCtrls].hwnd ) return( (HWND) 0 ); // CreateWindow failed for some reason // SendMessage (toolCtrl[cntToolCtrls].hwnd, WM_SETFONT, (UINT) hfontTools, MAKELONG (TRUE, 0) ); toolCtrl[cntToolCtrls].wType = TC_LABEL; hdc = GetDC (hwndTools); if( iWidth < 0 ) { toolCtrl[cntToolCtrls].iWidth = tmToolFont.tmAveCharWidth * abs(iWidth); } else if( iWidth == 0 ) { #ifdef WIN32 SIZE size; GetTextExtentPoint( hdc, szLabel, lstrlen(szLabel), &size ); toolCtrl[cntToolCtrls].iWidth = size.cx; #else toolCtrl[cntToolCtrls].iWidth = LOWORD( GetTextExtent( hdc, szLabel, lstrlen(szLabel) ) ); #endif } else { toolCtrl[cntToolCtrls].iWidth = iWidth; } toolCtrl[cntToolCtrls].iHeight = tmToolFont.tmHeight; if( (toolCtrl[cntToolCtrls].iHeight + (6*cyToolBorder)) > dyTools ) { dyTools = (toolCtrl[cntToolCtrls].iHeight + (6*cyToolBorder)); } ReleaseDC( hwndTools, hdc ); UpdatePositions( NULL ); return( toolCtrl[cntToolCtrls++].hwnd ); } // ************************************************************************ // FUNCTION : AddToolCombo (HANDLE hInst, INT iId, INT iWidth, DWORD dwStyle) // PURPOSE : // COMMENTS : // ************************************************************************ HWND AddToolCombo (HANDLE hInstance, INT iId, INT iWidth, DWORD dwStyle) { if( cntToolCtrls >= MAXCTRLS ) return( (HWND) 0 ); // No room left in our fixed array if( dwStyle==0 ) dwStyle = CBS_DROPDOWNLIST; toolCtrl[cntToolCtrls].hwnd = CreateWindow ( TEXT( "COMBOBOX" ), TEXT( "" ), WS_CHILD | // WS_CLIPSIBLINGS | WS_VISIBLE | dwStyle, 0, 0, 0, 0, hwndTools, (HMENU) iId, hInstance, NULL ); if( !toolCtrl[cntToolCtrls].hwnd ) return( (HWND) 0 ); // CreateWindow failed for some reason // SendMessage (toolCtrl[cntToolCtrls].hwnd, WM_SETFONT, (UINT)hfontTools, MAKELONG (TRUE, 0)); toolCtrl[cntToolCtrls].wType = TC_COMBO; if( iWidth < 0 ) { toolCtrl[cntToolCtrls].iWidth = tmToolFont.tmAveCharWidth * abs(iWidth); } else if( iWidth == 0 ) { toolCtrl[cntToolCtrls].iWidth = tmToolFont.tmAveCharWidth * 15; // just a default width } else { toolCtrl[cntToolCtrls].iWidth = iWidth; } toolCtrl[cntToolCtrls].iHeight = dyCombo; if( (toolCtrl[cntToolCtrls].iHeight + (6*cyToolBorder)) > dyTools ) { dyTools = (toolCtrl[cntToolCtrls].iHeight + (6*cyToolBorder)); } UpdatePositions( NULL ); return( toolCtrl[cntToolCtrls++].hwnd ); } // ************************************************************************ // FUNCTION : AddToolButton( HANDLE hInst, INT iId, LPTSTR szLabel, INT iWidth, INT iHeight, DWORD dwStyle ) // PURPOSE : // COMMENTS : // ************************************************************************ HWND AddToolButton( HANDLE hInstance, INT iId, LPTSTR szLabel, INT iWidth, INT iHeight, DWORD dwStyle ) { HDC hdc; if( cntToolCtrls >= MAXCTRLS ) return( (HWND) 0 ); // No room left in our fixed array if( dwStyle == 0 ) dwStyle = BS_PUSHBUTTON | BS_OWNERDRAW; toolCtrl[cntToolCtrls].hwnd = CreateWindow ( TEXT( "BUTTON" ), szLabel, WS_CHILD | // WS_CLIPSIBLINGS | WS_VISIBLE | dwStyle, 0, 0, 0, 0, hwndTools, (HMENU)iId, hInstance, NULL ); if( !toolCtrl[cntToolCtrls].hwnd ) return( (HWND) 0 ); // CreateWindow failed for some reason // SendMessage (toolCtrl[cntToolCtrls].hwnd, WM_SETFONT, (UINT)hfontTools, MAKELONG (TRUE, 0)); toolCtrl[cntToolCtrls].wType = TC_BUTTON; hdc = GetDC (hwndTools); SelectObject (hdc, hfontTools); if( iWidth < 0 ) { toolCtrl[cntToolCtrls].iWidth = tmToolFont.tmAveCharWidth * abs(iWidth); toolCtrl[cntToolCtrls].iWidth += (6*cxToolBorder); } else if( iWidth == 0 ) { #ifdef WIN32 SIZE size; GetTextExtentPoint (hdc, szLabel, lstrlen(szLabel), &size); toolCtrl[cntToolCtrls].iWidth = size.cx; #else toolCtrl[cntToolCtrls].iWidth = LOWORD(GetTextExtent (hdc, szLabel, lstrlen(szLabel))); #endif toolCtrl[cntToolCtrls].iWidth += (6*cxToolBorder); } else { toolCtrl[cntToolCtrls].iWidth = iWidth; } if( iHeight < 0 ) { toolCtrl[cntToolCtrls].iHeight = tmToolFont.tmHeight; toolCtrl[cntToolCtrls].iHeight += (6*cyToolBorder); } else if( iHeight==0 ) { toolCtrl[cntToolCtrls].iHeight = dyTools - (6*cyToolBorder); } else { toolCtrl[cntToolCtrls].iHeight = iHeight; } if( (toolCtrl[cntToolCtrls].iHeight + (6*cyToolBorder)) > dyTools ) { dyTools = (toolCtrl[cntToolCtrls].iHeight + (6*cyToolBorder)); } if( dwStyle & BS_OWNERDRAW ) { toolCtrl[cntToolCtrls].hIcon = LoadIcon (hInstance, szLabel); } else { toolCtrl[cntToolCtrls].hIcon = NULL; } ReleaseDC( hwndTools, hdc ); UpdatePositions( NULL ); return toolCtrl[cntToolCtrls++].hwnd; } // ************************************************************************ // FUNCTION : DestroyToolBar (VOID) // PURPOSE : // COMMENTS : // ************************************************************************ BOOL DestroyToolBar( VOID ) { return( DeleteObject(hbrBtnFace) ); } // ************************************************************************ // FUNCTION : DrawButton (HDC hdc, RECT rect, BOOL bDown, HICON hIcon) // PURPOSE : // COMMENTS : // ************************************************************************ VOID DrawButton (HDC hdc, RECT rect, BOOL bDown, HICON hIcon) { HBRUSH hBrush, hbrFrame, hbrBtnFace, hbrHilite, hbrShadow; RECT border; INT i; hbrFrame = CreateSolidBrush( rgbFrame ); hbrBtnFace = CreateSolidBrush( rgbBtnFace ); hbrHilite = CreateSolidBrush( rgbHilite ); hbrShadow = CreateSolidBrush( rgbShadow ); FillRect (hdc, &rect, hbrBtnFace); if( hIcon ) { if( bDown ) { DrawIcon (hdc, rect.left + (4*cyToolBorder), rect.top + (4*cyToolBorder), hIcon); } else { DrawIcon (hdc, rect.left + (3*cyToolBorder), rect.top + (3*cyToolBorder), hIcon); } } hBrush = hbrFrame; border = rect; border.bottom = border.top + cyToolBorder; FillRect( hdc, &border, hBrush ); border = rect; border.right = border.left + cxToolBorder; FillRect( hdc, &border, hBrush ); border = rect; border.top = border.bottom - cyToolBorder; FillRect( hdc, &border, hBrush ); border = rect; border.left = border.right - cxToolBorder; FillRect( hdc, &border, hBrush ); for( i= 0; i<2; i++ ) { InflateRect( &rect, -cxToolBorder, -cyToolBorder ); hBrush = ( bDown? hbrShadow:hbrHilite ); border = rect; border.bottom = border.top + cyToolBorder; FillRect( hdc, &border, hBrush ); border = rect; border.right = border.left + cxToolBorder; FillRect( hdc, &border, hBrush ); if( !bDown ) { hBrush = hbrShadow; border = rect; border.top = border.bottom - cyToolBorder; FillRect( hdc, &border, hBrush ); border = rect; border.left = border.right - cxToolBorder; FillRect( hdc, &border, hBrush ); } } DeleteObject( hbrFrame ); DeleteObject( hbrBtnFace ); DeleteObject( hbrHilite ); DeleteObject( hbrShadow ); } // ************************************************************************ // FUNCTION : ToolsProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) // PURPOSE : // COMMENTS : // ************************************************************************ LONG CALLBACK ToolsProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; INT iType, idCtrl, msgCtrl, i; RECT rect, border; COLORREF clrColor = rgbToolBar; HWND hwndCtl; LONG lStyle; HBRUSH hBrush = hbrToolBar; LPDRAWITEMSTRUCT lpdi; HICON hIcon; switch( msg ) { case WM_CREATE: //DebugOut( "[ToolsProc] WM_CREATE" ); #ifdef NOCREATEFONT // CreateFont is failing in NT hfontTools = (HFONT)NULL; #else hfontTools = CreateFont(16, 0, 0, 0, 0, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, NULL); if( !hfontTools ) { MessageBox( GetFocus(), TEXT( "Failed To Create Font" ), TEXT( "StatusProc" ), MB_OK ); } #endif hdc = GetDC( hwnd ); SelectObject( hdc, hfontTools ); GetTextMetrics( hdc, &tmToolFont ); ReleaseDC( hwnd, hdc ); //DebugOut( "[ToolsProc] WM_CREATE (exit)" ); return( DefWindowProc( hwnd, msg, wParam, lParam ) ); case WM_SIZE: UpdatePositions(hwnd); break; #ifdef WIN32 case WM_CTLCOLORLISTBOX: case WM_CTLCOLOREDIT: case WM_CTLCOLORSTATIC: case WM_CTLCOLORBTN: case WM_CTLCOLORDLG: case WM_CTLCOLORMSGBOX: case WM_CTLCOLORSCROLLBAR: iType = msg - WM_CTLCOLORMSGBOX; hdc = (HDC)wParam; hwndCtl = (HWND)lParam; #else case WM_CTLCOLOR: hdc = wParam; hwndCtl = LOWORD( lParam ); iType = HIWORD ( lParam ); #endif switch (iType) { case CTLCOLOR_EDIT: //Edit control clrColor = rgbBtnFace; hBrush = hbrToolBar; break; case CTLCOLOR_LISTBOX: //List-box control lStyle = GetWindowLong (hwndCtl, GWL_STYLE); if( lStyle & CBS_SIMPLE ) { clrColor = rgbToolBar; hBrush = hbrToolBar; } else { clrColor = rgbBtnFace; hBrush = hbrToolBar; } break; case CTLCOLOR_STATIC: clrColor = rgbBtnFace; hBrush = hbrBtnFace; break; case CTLCOLOR_BTN: clrColor = rgbBtnFace; hBrush = hbrBtnFace; break; case CTLCOLOR_SCROLLBAR: case CTLCOLOR_DLG: case CTLCOLOR_MSGBOX: default: return FALSE; } SetBkColor(hdc, clrColor); return (LONG)hBrush; case WM_PAINT: hdc = BeginPaint (hwnd, &ps); GetClientRect (hwnd, &rect); /* Shade the top of the bar white */ hBrush = CreateSolidBrush( rgbDirectLight ); border = rect; border.bottom = border.top + cyToolBorder; FillRect (hdc, &border, hBrush); DeleteObject (hBrush); /* Shade the bottom of the bar dark gray */ hBrush = CreateSolidBrush( rgbShadow ); border = rect; border.top = border.bottom - cyToolBorder; FillRect (hdc, &border, hBrush); DeleteObject (hBrush); EndPaint (hwnd, &ps); return DefWindowProc (hwnd, msg, wParam, lParam); case WM_DRAWITEM: // Indicates that an owner-draw control needs to be redrawn. lpdi = (LPDRAWITEMSTRUCT)lParam; switch( lpdi->itemAction ) { // handle normal drawing of button, but check if its selected or focus case ODA_SELECT: case ODA_DRAWENTIRE: // handle button pressed down select state -- button down bitmap // text is right & down 2 pixels hIcon = NULL; for( i=0; i< cntToolCtrls; i++ ) { if( toolCtrl[i].hwnd == lpdi->hwndItem ) { hIcon = toolCtrl[i].hIcon; } } if( lpdi->itemState & ODS_SELECTED ) { DrawButton( lpdi->hDC,lpdi->rcItem, TRUE, hIcon ); } else { // not selected -- button up; text is in normal position DrawButton( lpdi->hDC,lpdi->rcItem, FALSE, hIcon ); } return( TRUE ); } break; case WM_COMMAND: #ifdef WIN32 idCtrl = LOWORD( wParam ); msgCtrl = HIWORD( wParam ); hwndCtl = (HWND) lParam; #else idCtrl = wParam; msgCtrl = HIWORD( lParam ); hwndCtl = LOWORD( lParam ); #endif if( GetWindowLong( hwndCtl, GWL_STYLE ) & BS_OWNERDRAW ) { if( msgCtrl == BN_DOUBLECLICKED ) { PostMessage( hwndCtl, WM_LBUTTONDOWN, 0, 0 ); return( TRUE ); } } PostMessage (hwndMain, msg, wParam, lParam); return DefWindowProc (hwnd, msg, wParam, lParam); default: return( DefWindowProc( hwnd, msg, wParam, lParam ) ); } return( 0L ); } // ======================================================================== // STATUS BAR FUNCTIONS // ======================================================================== // ************************************************************************ // FUNCTION : // PURPOSE : // COMMENTS : // ************************************************************************ BOOL InitStatusBar( HANDLE hInstance ) { WNDCLASS wndclass; hbrStatus = CreateSolidBrush( rgbBtnFace ); wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = (WNDPROC)StatusProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = NULL; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); wndclass.hbrBackground = hbrStatus; wndclass.lpszMenuName = NULL; wndclass.lpszClassName = TEXT( "SamplerStatus" ); if( !RegisterClass(&wndclass) ) return( FALSE ); wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = (WNDPROC)StatusFieldProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = NULL; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); wndclass.hbrBackground = hbrStatus; wndclass.lpszMenuName = NULL; wndclass.lpszClassName = TEXT( "StatusField" ); if( !RegisterClass (&wndclass) ) return( FALSE ); } // ************************************************************************ // FUNCTION : // PURPOSE : // COMMENTS : // ************************************************************************ BOOL CreateStatusBar (HWND hwnd, HANDLE hInstance, INT iId) { cxStatusBorder = GetSystemMetrics (SM_CXBORDER); cyStatusBorder = GetSystemMetrics (SM_CYBORDER); //DebugOut( ": Calling CreateWindow" ); hwndStatus = CreateWindow ( TEXT( "SamplerStatus" ), TEXT( "SamplerStatus" ), WS_CHILD //| WS_CLIPSIBLINGS | WS_BORDER | WS_VISIBLE, 0, 0, 0, 0, hwnd, (HMENU)iId, hInstance, NULL); if (!hwndStatus) { return FALSE; } //DebugOut( "CreateWindow Succeeded" ); return TRUE; } // ************************************************************************ // FUNCTION : // PURPOSE : // COMMENTS : // ************************************************************************ int StatusBarHeight (HWND hwnd) { RECT rect; GetClientRect( hwndStatus, &rect ); return rect.bottom-rect.top; hwnd; // unreferenced } // ************************************************************************ // FUNCTION : // PURPOSE : // COMMENTS : // ************************************************************************ BOOL AdjustStatusBar (HWND hwnd) { RECT rect; GetClientRect (hwnd, &rect); MoveWindow (hwndStatus, rect.left-cxStatusBorder, rect.bottom - dyStatus + cyStatusBorder, rect.right - rect.left + (cxStatusBorder*2), dyStatus, TRUE); return TRUE; } // ************************************************************************ // FUNCTION : // PURPOSE : // COMMENTS : // ************************************************************************ HWND AddStatusField (HANDLE hInstance, INT iId, INT iMin, INT iMax, BOOL bNewGroup) { LONG lStyle; if( cntStatusField >= MAXSTATUS ) return( (HWND) 0 ); // No room left in our fixed array statusField[cntStatusField].hwnd = CreateWindow( TEXT( "StatusField" ), TEXT( "" ), WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hwndStatus, (HMENU)iId, hInstance, NULL ); if( !statusField[cntStatusField].hwnd ) return( (HWND) 0 ); // CreateWindow failed for some reason if( iMin < 0 ) { statusField[cntStatusField].iMinWidth = tmStatusFont.tmAveCharWidth*abs(iMin); } else { statusField[cntStatusField].iMinWidth = iMin; } if( iMax < 0 ) { statusField[cntStatusField].iMaxWidth = tmStatusFont.tmAveCharWidth*abs(iMax); } else { statusField[cntStatusField].iMaxWidth = iMax; } if( bNewGroup ) { lStyle = GetWindowLong( statusField[cntStatusField].hwnd, GWL_STYLE ); lStyle |= WS_GROUP; SetWindowLong( statusField[cntStatusField].hwnd, GWL_STYLE, lStyle ); } return( statusField[cntStatusField++].hwnd ); } // ************************************************************************ // FUNCTION : // PURPOSE : // COMMENTS : // ************************************************************************ BOOL DestroyStatusBar (VOID) { return( DeleteObject( hbrStatus ) ); } // ************************************************************************ // FUNCTION : // PURPOSE : // COMMENTS : // ************************************************************************ LONG CALLBACK StatusProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; INT x, y, i; INT wAvailWidth, wFlexWidth, cntFlexWidth, wNeedWidth, cntNeedWidth; RECT rect, border; HBRUSH hBrush; switch (msg) { case WM_CREATE: #ifdef NOCREATEFONT // CreateFont is failing in NT hfontStatus = (HFONT)NULL; #else hfontStatus = CreateFont(16, 0, 0, 0, 0, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, NULL); if( !hfontStatus ) { MessageBox( GetFocus(), TEXT( "Failed To Create Font" ), TEXT( "StatusProc" ), MB_OK ); } #endif hdc = GetDC (hwnd); SelectObject (hdc, hfontStatus); GetTextMetrics (hdc, &tmStatusFont); cxStatusBorder = GetSystemMetrics (SM_CXBORDER); cyStatusBorder = GetSystemMetrics (SM_CYBORDER); cxFrame = 3*cxStatusBorder; cyFrame = 3*cyStatusBorder; dyField = tmStatusFont.tmHeight + (2*cyStatusBorder); dyStatus = dyField + (2*cyFrame); ReleaseDC (hwnd, hdc); return DefWindowProc (hwnd, msg, wParam, lParam); case WM_SIZE: if( cntStatusField ) { GetClientRect (hwnd, &rect); wAvailWidth = rect.right - rect.left - (cxStatusBorder*8); wNeedWidth = 0; cntNeedWidth = 0; cntFlexWidth = 0; /* First Pass: Dole out to fields that have a minimum need */ for (i=0; i0) && (statusField[i].iMaxWidth ==0) ) { ++cntFlexWidth; } /* For those that have a max that is greater then their min... */ /* Includes (0,n) and (n,>n) */ if( statusField[i].iMaxWidth > statusField[i].iGiveWidth ) { wNeedWidth += (statusField[i].iMaxWidth - statusField[i].iGiveWidth); ++cntNeedWidth; } } /* Second Pass: Dole out to fields that have a stated maximum need */ /* This will also hit those who had no minimum, but did have a maximum */ /* It will still not give anything to those with no min, no max */ if( (cntNeedWidth > 0) && (wAvailWidth > 0) ) { if( wNeedWidth > wAvailWidth ) { wNeedWidth = wAvailWidth; } wNeedWidth = wNeedWidth / cntNeedWidth; for( i=0; i statusField[i].iGiveWidth ) { statusField[i].iGiveWidth += wNeedWidth; wAvailWidth -= (statusField[i].iGiveWidth + cxStatusBorder*2); if( GetWindowLong(statusField[i].hwnd, GWL_STYLE) & WS_GROUP ) { wAvailWidth -= cxStatusBorder*4; } } } } /* Third Pass: Dole out the remaining to fields that want all they can get */ /* This includes those who had a minimum, but no maximum */ if( (cntFlexWidth > 0) && (wAvailWidth > 0) ) { wFlexWidth = wAvailWidth / cntFlexWidth; for( i=0; i