August 31, 2012

Hiding the icon in a Visual FoxPro form

By Mike Lewis

A colleague recently asked if it was possible to hide the icon in a VFP form. She was referring to the icon at the left end of the title bar - the one you click to reveal the control menu.

One way to do that is to set the form's ControlBox property to .F. That will hide the icon, but it will also hide the Minimize, Maximize and Close buttons at the other end of the title bar. If that's not what you want, you could add your own version of those buttons to the form itself, but, of course, they won't look like real title-bar buttons.

An alternative method is to retain the icon but to make it invisible. That way, the buttons at the right-hand end will still appear, and you will still be able to open the control menu (by clicking in the space which the icon would otherwise occupy).

To create an invisible icon, create a new 16 x 16 image in your favorite image editing tool. Fill it with the "transparent" color (that is, with an alpha channel of zero). Then save the image as an ICO file, and use that file for the form's Icon property.

One small disadvantage of this method is that there will be a gap between the form's caption and the left edge of the title bar, which might look odd. But if you can live with that, the method should work fine.

1 comment:

  1. Hi,
    use WM_SETICON winapi message *AFTER* set any titlebar properties (Caption, MinButton, ControlBox, Closable, etc), or Bind to Show event.
    Look at RemoveIcon method in this code:

    [CODE]
    LOCAL oDlg AS xmsgbox
    m.oDlg = CREATEOBJECT('xmsgbox')
    m.oDlg.Show
    ? m.oDlg.GetResult()

    *--
    * http://msdn.microsoft.com/en-us/library/windows/desktop/ms632643.aspx
    *--
    #ifndef WM_SETICON
    #define WM_SETICON 0x0080
    #endif
    * wParam:
    #ifndef ICON_SMALL
    #define ICON_BIG 1 && large icon for the window (Alt+Tab)
    #define ICON_SMALL 0 && small icon for the window caption
    #define ICON_SMALL2 2 && small icon provided by the application
    #endif
    *--

    DEFINE CLASS xmsgbox AS Form
    AllowOutput = .F.
    AlwaysOnTop = .T.
    AutoCenter = .T.
    BorderStyle = 2 && fixed dialog
    Caption = _Screen.Caption
    Desktop = .T.
    MinButton = .F.
    MaxButton = .F.
    ShowWindow = 1 && In Top-Level Form
    ShowInTaskbar = .F.
    WindowType = 1
    Height = 160
    Width = 280
    ColorSource = 5 && Window COlors
    FontName = 'Segoe UI'

    nResult = 0
    ADD OBJECT shape1 AS Shape WITH BorderStyle = 0, Left = -2
    ADD OBJECT cmgBtnBar AS cmgButtons

    PROCEDURE Show
    IF VAL(OS(3)) < 6
    This.FontName = 'Tahoma'
    ENDIF
    WITH This.cmgBtnBar
    This.Closable = .CanCancel() && if you have a .Cancel commandbutton
    .Reset
    ENDWITH
    WITH This.Shape1 AS Shape
    .Top = This.cmgBtnBar.Top - 5
    .Width = This.Width + 4
    .Height = This.Height - .Top + 2
    .Anchor = 15
    .ZOrder(1)
    ENDWITH
    This.RemoveIcon
    ENDPROC

    PROCEDURE RemoveIcon
    DECLARE Long SendMessage IN WIN32API ;
    Integer hWnd, Integer uMsg, Integer wParam, Long lParam
    *--
    SendMessage(This.HWnd, WM_SETICON, ICON_SMALL, 0)
    SendMessage(This.HWnd, WM_SETICON, ICON_SMALL2, 0)
    ENDPROC

    PROCEDURE cmgBtnBar.OnButton(nID)
    Thisform.nResult = m.nID
    Thisform.Hide
    ENDPROC

    FUNCTION GetResult()
    RETURN This.nResult
    ENDFUNC
    ENDDEFINE

    DEFINE CLASS cmgButtons AS CommandGroup
    BorderStyle = 0
    BackStyle = 0
    Value = 0
    nExtraMargin = 4

    PROCEDURE Init
    This.ButtonCount = 2
    WITH This.Buttons(1) AS CommandButton
    .Name = 'cmdOk'
    .Caption = 'OK'
    .Default = .T.
    .AddProperty('nID', 1) &&IDOK
    ENDWITH
    WITH This.Buttons(2)
    .Caption = 'Cancel'
    .Cancel = .T.
    .Left = This.cmdOK.Left + This.cmdOK.Width + 8
    .Top = This.cmdOK.Top
    .AddProperty('nID', 2) &&IDCANCEL
    ENDWITH
    ENDPROC

    PROCEDURE Reset
    WITH This
    .SetAll('FontName', Thisform.FontName)
    .AutoSize = .T.
    .Left = Thisform.Width - .Width - .nExtraMargin
    .Top = Thisform.Height - .Height - .nExtraMargin
    .Anchor = 12 && keep on lower right corner of form
    ENDWITH
    ENDPROC

    PROCEDURE InteractiveChange
    IF This.Value >= 1 && Skip CTRL+0
    RAISEEVENT(This, 'OnButton', This.Buttons(This.Value).nID)
    ENDIF
    ENDPROC

    PROCEDURE OnButton(nID)
    *
    ENDPROC

    FUNCTION CanCancel()
    LOCAL oBtn
    FOR EACH oBtn IN This.Buttons
    IF m.oBtn.Cancel
    RETURN .T.
    ENDIF
    NEXT
    RETURN .F.
    ENDFUNC
    ENDDEFINE

    [/CODE]

    Sorry for my "spanglish" :-)
    ---
    Alberto Martínez (amarcruz at yahoo+com)

    ReplyDelete