No announcement yet.

Owner Drawn Status Bar

  • Filter
  • Time
  • Show
Clear All
new posts

  • Cliff Nichols
    Thank you MCM...I see what I was doing wrong (add one to the :doh count)
    (I was passing GetSysColor(%COLOR_WINDOW) as a parameter, and not the results of GetSysColor(%COLOR_WINDOW)

    I was working on a pure DDT idea vs pure SDK idea for an example, (for VB Refugees), but immediately I ran into problems...(maybe because I am learning more SDK these days, and forgetting DDT)

    Hopefully this weekend I can find time to break it all down into a tutorial 101 kinda thing

    Leave a comment:

  • Michael Mattias
    GetSysColor[Brush] (%COLOR_WINDOW) I think.

    (somewhere there's something about using system colors to do with when you have to add or subtract one, too, but I can't remember that right now).

    Leave a comment:

  • Cliff Nichols
    I can whip something up a bit later, but at the moment the one drawback I have (and I KNOWWWWW it must be something simple) is what color is the default Windows/Dialog background color?
    I tried %GREY and %LTGREY and even tried %COLOR_BTNFACE (But that was almost black)

    I know its something simple to do with a brush though

    Leave a comment:

  • Michael Mattias
    Do you have this working?

    If so, maybe a demo in source code forum would be a nice thing to do.

    If not, beg me and I'll create one. Could be a 'fun' little program I could knock off in an hour or so.


    Leave a comment:

  • Cliff Nichols
    Thank you MCM....that cleared a bit up (although in this case my solution is "Cheating" of sorts) since I noticed even when I almost had things correct, that callback would erase and repaint.

    So for the time being (until I can understand more fully) I took Jose's premise and small modification to set different colors depending on what I want to show the user.

    Only bad part, is to the color-blind (but from my understanding, they can tell the differences between stoplight colors (if not just the position), my idea is partially following suit.

    Red = Error (OMG...something is wrong)
    Yellow = Communication (or something is changing)
    Green = All is fine ( need to panic....ALLLL IS FINNNNE.....Do NOT PANIC) '<--- Sorry bad spin on Animal House quote

    Although I consider it "Cheating" it works....(I just hate not having the time to handle and understand what I am handling without "Mama M$ cleaning up behind me")

    Leave a comment:

  • Michael Mattias
    DrawItem.CtlType = %ODT_STATIC
    DrawItem.CtlId = hStatus

    You don't set the members of the DRAWITEMSTUCT; Windows sets those for your use.

    I have the text for owner-drawn status bars for this on my disk version of SDK, let me see if I can find it online and give you a link...

    found it..

    Basically you have to send the SB_SETTEXT message with the SBT_OWNERDRAW value in uflag; and the control will then send you a WM_DRAWITEM with appropriate DRAWITEMSTRUCT to use for that status bar part. This step seems to be missing from your code.

    According to the doc, Windows will re-send WM_DRAWITEM messages for each statusbar part whenever that part needs to be redrawn.


    Leave a comment:

  • Cliff Nichols
    Basically the code for the StatusBar is
                hStatus = CreateStatusWindow(%WS_CHILD OR %WS_VISIBLE OR %SBS_SIZEGRIP, "", hWnd, %ID_STATUSBAR)
                DIM prts(0 TO 11) AS LONG
                GetClientRect hStatus, rc
    '*** Dimension the parts
                prts(0) = rc.nRight * 0.05     : prts(1) = rc.nRight * 0.15     'Port:Portnum
                prts(2) = rc.nRight * 0.16     : prts(3) = rc.nRight * 0.25     'Space:Baud
                prts(4) = rc.nRight * 0.35     : prts(5) = rc.nRight * 0.36     'Baudratenum:Space
                prts(6) = rc.nRight * 0.43     : prts(7) = rc.nRight * 0.78     'Status:PortStatus
                prts(8) = rc.nRight * 0.79     : prts(9) = rc.nRight * 0.85     'Space:VXM
                prts(10) = rc.nRight * 0.95     : prts(11) = rc.nRight * 1      'VXMStatus:Space
                Sendmessage hStatus, %SB_SETPARTS, 12, VARPTR(prts(0))
    And my 1st poor attempt
                        DrawItem.CtlType = %ODT_STATIC
                        DrawItem.CtlId = hStatus
                        DrawItem.ItemId = 7
                        DrawItem.ItemAction = %ODA_DRAWENTIRE
                        DrawItem.ItemState = %ODS_SELECTED
                        DrawItem.HwndItem = hStatus
                        DrawItem.hDC = GetDC(hStatus)
                        GetClientRect(hStatus, DrawItem.rcItem)
                        @zp = " Port Closed" + " - " + "Already Open in Other App"
                        DrawItem.ItemData = VARPTR(zp)
                        DSS_StatusbarDrawItem(hStatus, DrawItem, %WHITE, %RED)
    Which obviously is not quite right, because I am only guessing at the correct values. (Currently the whole statusbar (except 1 part) show red background, with white blocks (I am guessing are nulls) rather than the text and just 1 part being red, but like I said, I am guessing at what value should be what?
    Last edited by Cliff Nichols; 3 Apr 2008, 09:32 AM. Reason: Left stuff off

    Leave a comment:

  • Michael Mattias
    Is that a Statusbar control (Classname="msctls_statusbar32"), or a STATIC control used as a statusbar?

    (Show the line of code used to create that control).

    The "official" status bar control is one of the Microsoft Common Controls, and slighltly different rules apply to many of the Common Controls.

    Leave a comment:

  • Cliff Nichols
    started a topic Owner Drawn Status Bar

    Owner Drawn Status Bar

    I did a bunch of searches in PB for "Owner Drawn Status", "Draw Status", and other variations for an Owner Drawn Status bar, and the only usable result is Jose Roca's EXCELLENT example Statusbar wrapper.

    code to place in your Window Callback
           ' Ownerdraw statusbar
              DSS_StatusbarDrawItem hWnd, LPARAM           '<--- See Jose Roca's statusbar wrapper
    and the wrapper function itself
    SUB DSS_StatusbarDrawItem (BYVAL hDlg AS  DWORD, BYVAL lParam AS LONG)
        LOCAL hBrush AS DWORD
        LOCAL clrFg AS DWORD
        LOCAL clrBk AS DWORD
        lpdis = lParam
    ''msgbox str$(@lpdis.CtlType)
    '    InflateRect @lpdis.rcItem, -1, -1 'test with smaller rect for "better" look
        DECR @lpdis.rcItem.nRight          'or maybe this is better..?
        DECR @lpdis.rcItem.nBottom
        clrBk = %BLUE
        clrFg = %WHITE
        SELECT CASE @lpdis.itemID
           CASE 1 : clrBk = %YELLOW : clrFg = %RED
           CASE 2 : clrBk = %RED : clrFg = %YELLOW
           CASE 3 : clrBk = RGB(0,160,0) : clrFg = %WHITE
        END SELECT
        hBrush = CreateSolidBrush(clrBk)
        FillRect @lpdis.hDC, @lpdis.rcItem, hBrush
        SetBkColor @lpdis.hDC, clrBk
        SetTextColor @lpdis.hDC, clrFg
        DeleteObject hBrush
        zp = @lpdis.itemData
    '    DrawText @lpdis.hDC, @zp, LEN(@zp), @lpdis.rcItem, %DT_CENTER OR %DT_SINGLELINE OR %DT_VCENTER
        DrawText @lpdis.hDC, @zp, LEN(@zp), @lpdis.rcItem, %DT_SINGLELINE OR %DT_VCENTER
    ' ==========================================================================
    Although an excellent wrapper and great example to work with, (worked perfect without having to modify code), I wanted to take things a step farther and more generic (if only to understand how the code works).

    According to Docs (If I read them right) then WPARAM = the control you want to change, and LPARAM = DRAWITEMSTRUCT

    Breaking down to not use the callback, but a function directly called, so far I have come up with
    SUB DSS_StatusbarDrawItem (BYVAL HwndWindow AS DWORD, BYVAL DrawItem AS DRAWITEMSTRUCT, ForeGroundColor AS DWORD, BackGroundColor AS DWORD)
        LOCAL hBrush AS DWORD
    '    InflateRect @lpdis.rcItem, -1, -1 'test with smaller rect for "better" look
        DECR DrawItem.rcItem.nRight          'or maybe this is better..?
        DECR DrawItem.rcItem.nBottom
        hBrush = CreateSolidBrush(BackGroundColor)
        FillRect DrawItem.hDC, DrawItem.rcItem, hBrush
        SetBkColor DrawItem.hDC, BackGroundColor
        SetTextColor DrawItem.hDC, ForeGroundColor
        DeleteObject hBrush
        zp = DrawItem.itemData
    '    DrawText @lpdis.hDC, @zp, LEN(@zp), @lpdis.rcItem, %DT_CENTER OR %DT_SINGLELINE OR %DT_VCENTER
        DrawText DrawItem.hDC, @zp, LEN(DrawItem.itemData), DrawItem.rcItem, %DT_SINGLELINE OR %DT_VCENTER
    ' ==========================================================================
    However I am having a lil' bit of trouble understanding each of the elements of the UDT for DrawItemStruct, that I hope someone can help clear up.

    I tried checking values of each from the original working code, but nothing matches up with the defined values in Win32Api.Inc, so I am TOTALLY confused

    My thoughts on the elements are:
    CtlType = ODT_BUTTON, 'Owner-drawn button
    ODT_COMBOBOX 'Owner-drawn combo box
    ODT_LISTBOX 'Owner-drawn list box
    ODT_LISTVIEW 'List view control
    ODT_MENU 'Owner-drawn menu item
    ODT_STATIC 'Owner-drawn static control
    ODT_TAB 'Tab control
    '<--- CtlType shows absolutely nothing for StatusBar, so I am guessing Static label is used in statusbar?
    CtlID = Specifies the identifier of the combo box, list box, button, or static control. This member is not used for a menu item.
    '<--- So if I declare HwndStatus = 1000 then is CtlId 1000? or the Windows handle that results from creation? or 0 since not a combo, list, button, or label?
    itemID = Specifies the menu item identifier for a menu item (it goes on from there, but no mention of a statusbar
    '<--- In this case if I split the statusbar into parts, is this the value I plug in for say part 8?????
    itemAction = ODA_DRAWENTIRE 'The entire control needs to be drawn.
    ODA_FOCUS 'Check if has focus
    ODA_SELECT 'The selection status has changed.
    '<--- Since I am not setting focus or selecting, but just changing colors, I assume I have to pass ODA_DRAWENTIRE?
    itemState = ODS_CHECKED 'The menu item is to be checked. This bit is used only in a menu.
    ODS_COMBOBOXEDIT The drawing takes place in the selection field (edit control) of an ownerdrawn combo box.
    ODS_DEFAULT The item is the default item.
    ODS_DISABLED The item is to be drawn as disabled.
    ODS_FOCUS The item has the keyboard focus.
    ODS_GRAYED The item is to be grayed. This bit is used only in a menu.
    ODS_SELECTED The menu item's status is selected.
    hwndItem = Identifies the control for combo boxes, list boxes, buttons, and static controls. For menus, this member identifies the menu containing the item.
    '<--- So is this the value I plug in for my part of the statusbar?????
    HDC hDC;
    '<--- For the time being until I clear up the other parts, I assume this is the Hdc of the statusbar? (or would it be a part of the statusbar?
    RECT rcItem; <--- For the time being I assume this will be the rect of the part I wish to change
    DWORD itemData; '<---Not sure if this will be my text? or some other value?
    End Type

    Hopefully not toooooo confusing, but I am just trying to understand the docs when the docs do not even state anything to do with a statusbar.....which also makes me wonder, if it works, does it mean I am using the right api? or just lucking out that it works?