// status bar class // drawn in parent window rather than independant window #include #pragma hdrstop #include // status box ********************************************** StatusBox::StatusBox(char *T,int X,int W) { Text=strdup(T); x=X; w=W; } StatusBox::~StatusBox() { if (Text) delete[] Text; } void StatusBox::SetText(char *T) { if (Text) delete[] Text; Text=strdup(T); } // status bar ********************************************** // void Paint(HDC dc); EV_START(StatusBar) EV_MESSAGE(WM_KEYUP,WMKeyUp) EV_MESSAGE(WM_KEYDOWN,WMKeyDown) EV_MESSAGE(WM_SETFOCUS,WMFocus) EV_MESSAGE(WM_SIZE,WMSize) EV_MESSAGE(WM_GETMINMAXINFO,WMGetMinMaxInfo) EV_MESSAGE(WM_MENUSELECT,WMMenuSelect) EV_END StatusBox *StatusBar::AddBox(char *T,int w) { StatusBox *S=new StatusBox(T,dyBorderx8 + Pos,w*CharWidth); BoxList.AddTail(S); Pos+=w*CharWidth+dyBorderx8; return S; } void StatusBar::InsertBox(int After,char *T,int w) { StatusBox *Box=BoxList[After]; StatusBox *S=new StatusBox(T,Box->x+Box->w+dyBorderx8,w*CharWidth); S->SetText(T); BoxList.AddAfter(S,Box); BoxList.GetNext(S); while (S) { S->x+=w*CharWidth+dyBorderx8; BoxList.GetNext(S); } DrawText(Box); Invalidate(); } StatusBar::StatusBar(Object *P,int w,BOOL NumBox,BOOL CapsBox) : Object(P) { dyBorder = GetSystemMetrics(SM_CYBORDER); dyBorderx2 = dyBorder * 2; dyBorderx3 = dyBorder * 3; dyBorderx8 = dyBorder * 8; dyBorderx9 = dyBorder * 9; HDC dc = GetDC(NULL); int Fntheight = MulDiv(-10, GetDeviceCaps(dc, LOGPIXELSY), 72); Font = CreateFont(Fntheight, 0, 0, 0, 400, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "Helv"); SelectObject(dc, Font); TEXTMETRIC tm; GetTextMetrics(dc, &tm); ReleaseDC(NULL, dc); dyStatbar = tm.tmHeight + tm.tmExternalLeading + (7*dyBorder); CharWidth = tm.tmMaxCharWidth; Pos=0; TextBox=AddBox("",w); NumLock = NumBox ? AddBox("",3) : NULL; CapsLock = CapsBox ? AddBox("",3) :NULL; nMenu=0; OldText=NULL; } StatusBar::~StatusBar() { if (OldText) delete[] OldText; DeleteObject(Font); } BOOL StatusBar::SetupWindow() { nMenu=0; ParsePopup(GetMenu(ParentHWnd)); return TRUE; } void StatusBar::SetText(char *T) { TextBox->SetText(T); DrawText(TextBox); } void StatusBar::SetText(int Box,char *T) { StatusBox *S=BoxList[Box]; S->SetText(T); DrawText(S); } void StatusBar::DrawText(StatusBox *S) { if (!S->Text) return; RECT rc,rcTemp; HDC dc = GetDC(ParentHWnd); GetClientRect(ParentHWnd, &rc); rc.top = rc.bottom - dyStatbar; rcTemp.top = rc.top + dyBorder*4; rcTemp.bottom = rc.bottom - dyBorderx3; rcTemp.left = dyBorder + S->x; rcTemp.right = rcTemp.left + S->w- dyBorder; SelectObject(dc, Font); SetTextColor(dc, GetSysColor(COLOR_BTNTEXT)); SetBkColor(dc, GetSysColor(COLOR_BTNFACE)); ExtTextOut(dc, rcTemp.left + dyBorderx2, rcTemp.top, ETO_OPAQUE | ETO_CLIPPED, &rcTemp, S->Text, strlen(S->Text), NULL); ReleaseDC(ParentHWnd, dc); } void StatusBar::Paint(HDC dc) { RECT rc,rcTemp; GetClientRect(ParentHWnd, &rc); rc.top = rc.bottom - dyStatbar; /* Border color */ HBRUSH Brush = CreateSolidBrush(GetSysColor(COLOR_BTNFACE)); rcTemp = rc; rcTemp.top += dyBorderx2; FillRect(dc, &rcTemp, Brush); DeleteObject(Brush); /* Shadow color */ Brush = CreateSolidBrush(GetSysColor(COLOR_BTNSHADOW)); /* Top and left of boxes */ StatusBox *Ptr=BoxList.GetFirst(); while (Ptr) { rcTemp.top = rc.top + dyBorderx3; rcTemp.bottom = rcTemp.top + dyBorder; rcTemp.left = Ptr->x; rcTemp.right = rcTemp.left + Ptr->w; FillRect(dc, &rcTemp, Brush); rcTemp.bottom = rc.bottom - dyBorderx2; rcTemp.right = rcTemp.left + dyBorder; FillRect(dc, &rcTemp, Brush); BoxList.GetNext(Ptr); } DeleteObject(Brush); Brush = CreateSolidBrush(GetSysColor(COLOR_BTNHIGHLIGHT)); /* Bottom and right of boxes */ Ptr=BoxList.GetFirst(); while (Ptr) { rcTemp.top = rc.bottom - dyBorderx3; rcTemp.bottom = rcTemp.top + dyBorder; rcTemp.left = Ptr->x; rcTemp.right = rcTemp.left + Ptr->w; FillRect(dc, &rcTemp, Brush); rcTemp.top = rc.top + dyBorderx3; rcTemp.left = Ptr->x+Ptr->w; rcTemp.right = rcTemp.left + dyBorder; FillRect(dc, &rcTemp, Brush); BoxList.GetNext(Ptr); } /* Across the top */ rcTemp = rc; rcTemp.top += dyBorder; rcTemp.bottom = rcTemp.top + dyBorder; FillRect(dc, &rcTemp, Brush); DeleteObject(Brush); /* solid black line across top */ Brush = CreateSolidBrush(GetSysColor(COLOR_WINDOWTEXT)); rcTemp = rc; rcTemp.bottom = rcTemp.top; rcTemp.bottom += dyBorder; FillRect(dc, &rcTemp, Brush); DeleteObject(Brush); /* now the text, with the button face background */ SelectObject(dc, Font); SetTextColor(dc, GetSysColor(COLOR_BTNTEXT)); SetBkColor(dc, GetSysColor(COLOR_BTNFACE)); /* Text */ Ptr=BoxList.GetFirst(); while (Ptr) { if (Ptr->Text) { rcTemp.top = rc.top + dyBorder*4; rcTemp.bottom = rc.bottom - dyBorderx3; rcTemp.left = dyBorder + Ptr->x; rcTemp.right = rcTemp.left + Ptr->w - dyBorder; ExtTextOut(dc, rcTemp.left + dyBorderx2, rcTemp.top, ETO_OPAQUE | ETO_CLIPPED, &rcTemp, Ptr->Text, strlen(Ptr->Text), NULL); } BoxList.GetNext(Ptr); } } BOOL StatusBar::bInKeyDown=FALSE; BOOL StatusBar::WMKeyUp(TMSG &) { bInKeyDown = FALSE; return TRUE; } BOOL StatusBar::WMKeyDown(TMSG &Msg) { if ( !bInKeyDown ) { if ( Msg.wParam == VK_CAPITAL ) SetCapsLockText(); else if ( Msg.wParam == VK_NUMLOCK ) SetNumLockText(); bInKeyDown = TRUE; } return TRUE; } BOOL StatusBar::WMFocus(TMSG &) { SetCapsLockText(); SetNumLockText(); return TRUE; } void StatusBar::SetNumLockText() { /* Num Lock Text */ if (NumLock) { int State=GetKeyState(VK_NUMLOCK) & 0x0001; NumLock->SetText(State ? "NUM" : ""); DrawText(NumLock); } } void StatusBar::SetCapsLockText() { /* Caps Lock Text */ if (CapsLock) { int State=GetKeyState(VK_CAPITAL) & 0x0001; CapsLock->SetText(State ? "CAPS" : ""); DrawText(CapsLock); } } void StatusBar::Invalidate() { RECT rc; GetClientRect(ParentHWnd, &rc); rc.top = rc.bottom - dyStatbar; InvalidateRect(ParentHWnd,&rc,TRUE); } BOOL StatusBar::WMSize(TMSG &) { RECT rc; GetClientRect(ParentHWnd, &rc); rc.top = rc.bottom - dyStatbar; if (rc.top < StatRecSizeAdv.top) { /* Window SHRANK, need to invalidate current status rect */ InvalidateRect(ParentHWnd, &rc,FALSE); } else { /* Window GREW, need to invalidate prev status rect */ InvalidateRect(ParentHWnd, &StatRecSizeAdv,TRUE); } return TRUE; } BOOL StatusBar::WMGetMinMaxInfo(TMSG &) { GetClientRect(ParentHWnd, &StatRecSizeAdv); StatRecSizeAdv.top = StatRecSizeAdv.bottom - dyStatbar; return TRUE; } #define NOMENU 0 // WM_MENUSELECT BOOL StatusBar::WMMenuSelect(TMSG &Msg) { int nMenuID=NOMENU; WORD flags=LLHW(Msg); WORD item=LOWWPARAM(Msg.wParam); if (HILP32(Msg) == NULL && flags == 0xffff) { // Exiting menu mode. hMenu && hmenuPopup are NULL. //nMenuID = NOMENU; if (OldText) { SetText(OldText); delete[] OldText; OldText=NULL; } return TRUE; } else if (flags & MF_SYSMENU) { // System menu is up if (!(flags & MF_POPUP)) nMenuID = item; // System menu item is selected // System menu: item contains SC_* code. else nMenuID = IDM_SYSMENU; // System menu and no item is selected } else { if ((flags & MF_POPUP)) { // Pulling down a popup submenu: hmenuPopup contains popup handle. #ifdef WIN32 HMENU hm=GetSubMenu((HMENU) Msg.lParam,item); for (int i=0;iText ? TextBox->Text : ""); // null is reserved to indicate not in menu SetText(temp); return TRUE; } void StatusBar::ParsePopup(HMENU hm) { if (hm==NULL) return; HMENU hm2; int n=GetMenuItemCount(hm); for (int i=0;i