Home All Groups Group Topic Archive Search About

Put Date/Time on Right Side of Form.Caption

Author
9 Mar 2009 8:22 PM
David
I have an MDIForm and want to put Date/Time on Right Side of MDIForm.Caption next to the buttons.  

Any suggestions?

Thanks

David

Author
9 Mar 2009 9:16 PM
Jeff Johnson
"David" <dw85745***@earthlink.net> wrote in message
news:uXQxQTPoJHA.504@TK2MSFTNGP06.phx.gbl...

> I have an MDIForm and want to put Date/Time on Right Side of
> MDIForm.Caption next to the
> buttons.

This can only be done via subclassing.
Author
9 Mar 2009 10:15 PM
David
Thanks Mr. Johnson.

Only other ways I could think of were:

1) Put in a long caption string with the date/time to far right.
2)  Floating toolbar which would be positioned (overlaid) on caption.

Not a real fan of subclassing MDI.  Tried awhile back to subclass the
HScrollbar background color on each child.  1st child worked great but all
subsequent children for whatever reason received the same handle reference
as the 1st.  Hence, never worked as expected -- probably me.

Maybe will work this case but have a XProcess call to this MDI from an SDI
which uses MDI.Caption to ID so would prefer to not subclass.
Oh Well!


Show quoteHide quote
"Jeff Johnson" <i.get@enough.spam> wrote in message
news:OnsiBxPoJHA.4584@TK2MSFTNGP02.phx.gbl...
> "David" <dw85745***@earthlink.net> wrote in message
> news:uXQxQTPoJHA.504@TK2MSFTNGP06.phx.gbl...
>
>> I have an MDIForm and want to put Date/Time on Right Side of
>> MDIForm.Caption next to the
>> buttons.
>
> This can only be done via subclassing.
>
Author
9 Mar 2009 10:27 PM
C Kevin Provance
"David" <dw85745***@earthlink.net> wrote in message
news:uQQGYSQoJHA.1288@TK2MSFTNGP02.phx.gbl...
| Thanks Mr. Johnson.
|
| Only other ways I could think of were:
|
| 1) Put in a long caption string with the date/time to far right.
| 2)  Floating toolbar which would be positioned (overlaid) on caption.

1) You'd have to compensate for the resizing of that window, if it's
resizable.  You'll also have to consider that not everyone is using the same
font settings as you and therefore will not be displayed the same.

2) That would also require subclassing and is a lot more difficult that the
subclassing involved in doing what you wanted to do originally.
Author
9 Mar 2009 11:09 PM
Eduardo
For option 2, the main problem why you need to subclass is because you don't
have an event in VB that tells you that the form has moved.

I wrote a sample, but without subclassing, as I said, I doesn't take into
account if the form has moved.
To test it, start a new project, add another form (form2), add a label to
form2, and set the BorderStyle property of form2 to 0. And paste this code
to form1:

Private Declare Function SetWindowPos Lib "user32" _
    (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, _
    ByVal x As Long, y, ByVal cx As Long, ByVal cy As Long, _
    ByVal wFlags As Long) As Long
Private Declare Function GetWindowLong Lib "user32" Alias _
    "GetWindowLongA" (ByVal hwnd As Long, ByVal nindex _
    As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias _
    "SetWindowLongA" (ByVal hwnd As Long, ByVal nindex _
    As Long, ByVal dwnewlong As Long) As Long

Private Sub Form_Load()
    Form2.Label1.BackColor = vbBlue
    Form2.Label1.ForeColor = vbWhite
    Form2.Width = 1100
    Form2.Height = 210
    Form2.Label1.Move 0, 0, Form2.Width, Form2.Height
    Form2.Label1.Alignment = vbCenter
End Sub

Private Sub Form_Resize()
    Form2.Label1.Caption = Date
    Form2.Move Me.Left + Me.Width - Form2.Width - 1400, Me.Top + 130
    SetWindowLong Form2.hwnd, (-20), GetWindowLong(Form2.hwnd, (-20)) Or
&H80
    SetWindowPos Form2.hwnd, -1&, 0, 0, 0, 0, &H1 Or &H2 Or &H10 Or &H40
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Unload Form2
End Sub



Show quoteHide quote
"David" <dw85745***@earthlink.net> escribió en el mensaje
news:uQQGYSQoJHA.1288@TK2MSFTNGP02.phx.gbl...
> Thanks Mr. Johnson.
>
> Only other ways I could think of were:
>
> 1) Put in a long caption string with the date/time to far right.
> 2)  Floating toolbar which would be positioned (overlaid) on caption.
>
> Not a real fan of subclassing MDI.  Tried awhile back to subclass the
> HScrollbar background color on each child.  1st child worked great but all
> subsequent children for whatever reason received the same handle reference
> as the 1st.  Hence, never worked as expected -- probably me.
>
> Maybe will work this case but have a XProcess call to this MDI from an SDI
> which uses MDI.Caption to ID so would prefer to not subclass.
> Oh Well!
>
>
> "Jeff Johnson" <i.get@enough.spam> wrote in message
> news:OnsiBxPoJHA.4584@TK2MSFTNGP02.phx.gbl...
>> "David" <dw85745***@earthlink.net> wrote in message
>> news:uXQxQTPoJHA.504@TK2MSFTNGP06.phx.gbl...
>>
>>> I have an MDIForm and want to put Date/Time on Right Side of
>>> MDIForm.Caption next to the
>>> buttons.
>>
>> This can only be done via subclassing.
>>
>
>
Author
10 Mar 2009 2:49 AM
David
Thanks all for input and Eduardo for example.

Eduardo, there is a way to create an new event for a VB form but
somewhat more complicated than subclassing.

Will relook at subclassing as "best" option.

David


Show quoteHide quote
"Eduardo" <m*@mm.com> wrote in message news:gp47io$eu4$1@aioe.org...
> For option 2, the main problem why you need to subclass is because you
> don't have an event in VB that tells you that the form has moved.
>
> I wrote a sample, but without subclassing, as I said, I doesn't take into
> account if the form has moved.
> To test it, start a new project, add another form (form2), add a label to
> form2, and set the BorderStyle property of form2 to 0. And paste this code
> to form1:
>
> Private Declare Function SetWindowPos Lib "user32" _
>    (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, _
>    ByVal x As Long, y, ByVal cx As Long, ByVal cy As Long, _
>    ByVal wFlags As Long) As Long
> Private Declare Function GetWindowLong Lib "user32" Alias _
>    "GetWindowLongA" (ByVal hwnd As Long, ByVal nindex _
>    As Long) As Long
> Private Declare Function SetWindowLong Lib "user32" Alias _
>    "SetWindowLongA" (ByVal hwnd As Long, ByVal nindex _
>    As Long, ByVal dwnewlong As Long) As Long
>
> Private Sub Form_Load()
>    Form2.Label1.BackColor = vbBlue
>    Form2.Label1.ForeColor = vbWhite
>    Form2.Width = 1100
>    Form2.Height = 210
>    Form2.Label1.Move 0, 0, Form2.Width, Form2.Height
>    Form2.Label1.Alignment = vbCenter
> End Sub
>
> Private Sub Form_Resize()
>    Form2.Label1.Caption = Date
>    Form2.Move Me.Left + Me.Width - Form2.Width - 1400, Me.Top + 130
>    SetWindowLong Form2.hwnd, (-20), GetWindowLong(Form2.hwnd, (-20)) Or
> &H80
>    SetWindowPos Form2.hwnd, -1&, 0, 0, 0, 0, &H1 Or &H2 Or &H10 Or &H40
> End Sub
>
> Private Sub Form_Unload(Cancel As Integer)
>    Unload Form2
> End Sub
>
>
>
> "David" <dw85745***@earthlink.net> escribió en el mensaje
> news:uQQGYSQoJHA.1288@TK2MSFTNGP02.phx.gbl...
>> Thanks Mr. Johnson.
>>
>> Only other ways I could think of were:
>>
>> 1) Put in a long caption string with the date/time to far right.
>> 2)  Floating toolbar which would be positioned (overlaid) on caption.
>>
>> Not a real fan of subclassing MDI.  Tried awhile back to subclass the
>> HScrollbar background color on each child.  1st child worked great but
>> all subsequent children for whatever reason received the same handle
>> reference as the 1st.  Hence, never worked as expected -- probably me.
>>
>> Maybe will work this case but have a XProcess call to this MDI from an
>> SDI which uses MDI.Caption to ID so would prefer to not subclass.
>> Oh Well!
>>
>>
>> "Jeff Johnson" <i.get@enough.spam> wrote in message
>> news:OnsiBxPoJHA.4584@TK2MSFTNGP02.phx.gbl...
>>> "David" <dw85745***@earthlink.net> wrote in message
>>> news:uXQxQTPoJHA.504@TK2MSFTNGP06.phx.gbl...
>>>
>>>> I have an MDIForm and want to put Date/Time on Right Side of
>>>> MDIForm.Caption next to the
>>>> buttons.
>>>
>>> This can only be done via subclassing.
>>>
>>
>>
>
>
Author
10 Mar 2009 3:13 AM
Eduardo
Here is version 2 without subclassing:

Form1: add a Timer
Form2: set Borderstyle to 0 and add a Label

'Paste on Form2:

Private Sub Form_GotFocus()
    Form1.SetFocus
End Sub

'Paste on Form1:

Private Declare Function SetWindowPos Lib "user32" _
    (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, _
    ByVal x As Long, y, ByVal cx As Long, ByVal cy As Long, _
    ByVal wFlags As Long) As Long
Private Declare Function GetWindowLong Lib "user32" Alias _
    "GetWindowLongA" (ByVal hwnd As Long, ByVal nindex _
    As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias _
    "SetWindowLongA" (ByVal hwnd As Long, ByVal nindex _
    As Long, ByVal dwnewlong As Long) As Long

Private Sub Form_Load()
    Form2.Label1.BackColor = vbBlue
    Form2.Label1.ForeColor = vbWhite
    Form2.Width = 1100
    Form2.Height = 210
    Form2.Label1.Move 0, 0, Form2.Width, Form2.Height
    Form2.Label1.Alignment = vbCenter
    SetWindowLong Form2.hwnd, (-20), GetWindowLong(Form2.hwnd, _
        (-20)) Or 128
    Timer1.Interval = 1
    Form2.Show , Me
End Sub

Private Sub Form_Resize()
    PositionDateForm
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Unload Form2
End Sub


Private Sub Timer1_Timer()
    Static sLeftAnt As Long

    If sLeftAnt <> Me.Left Then
        sLeftAnt = Me.Left
        PositionDateForm
    End If
End Sub

Private Sub PositionDateForm()
    Form2.Label1.Caption = Date
    Form2.Move Me.Left + Me.Width - Form2.Width - 1400, Me.Top + 130
End Sub



Show quoteHide quote
"David" <dw85745***@earthlink.net> escribió en el mensaje
news:O3oDkrSoJHA.6064@TK2MSFTNGP06.phx.gbl...
> Thanks all for input and Eduardo for example.
>
> Eduardo, there is a way to create an new event for a VB form but
> somewhat more complicated than subclassing.
>
> Will relook at subclassing as "best" option.
>
> David
Author
10 Mar 2009 11:38 AM
David
Eduardo:  Thanks again for your code and effort on my part.

David

Show quoteHide quote
"Eduardo" <m*@mm.com> wrote in message news:gp4lsm$ov0$1@aioe.org...
> Here is version 2 without subclassing:
>
> Form1: add a Timer
> Form2: set Borderstyle to 0 and add a Label
>
> 'Paste on Form2:
>
> Private Sub Form_GotFocus()
>    Form1.SetFocus
> End Sub
>
> 'Paste on Form1:
>
> Private Declare Function SetWindowPos Lib "user32" _
>    (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, _
>    ByVal x As Long, y, ByVal cx As Long, ByVal cy As Long, _
>    ByVal wFlags As Long) As Long
> Private Declare Function GetWindowLong Lib "user32" Alias _
>    "GetWindowLongA" (ByVal hwnd As Long, ByVal nindex _
>    As Long) As Long
> Private Declare Function SetWindowLong Lib "user32" Alias _
>    "SetWindowLongA" (ByVal hwnd As Long, ByVal nindex _
>    As Long, ByVal dwnewlong As Long) As Long
>
> Private Sub Form_Load()
>    Form2.Label1.BackColor = vbBlue
>    Form2.Label1.ForeColor = vbWhite
>    Form2.Width = 1100
>    Form2.Height = 210
>    Form2.Label1.Move 0, 0, Form2.Width, Form2.Height
>    Form2.Label1.Alignment = vbCenter
>    SetWindowLong Form2.hwnd, (-20), GetWindowLong(Form2.hwnd, _
>        (-20)) Or 128
>    Timer1.Interval = 1
>    Form2.Show , Me
> End Sub
>
> Private Sub Form_Resize()
>    PositionDateForm
> End Sub
>
> Private Sub Form_Unload(Cancel As Integer)
>    Unload Form2
> End Sub
>
>
> Private Sub Timer1_Timer()
>    Static sLeftAnt As Long
>
>    If sLeftAnt <> Me.Left Then
>        sLeftAnt = Me.Left
>        PositionDateForm
>    End If
> End Sub
>
> Private Sub PositionDateForm()
>    Form2.Label1.Caption = Date
>    Form2.Move Me.Left + Me.Width - Form2.Width - 1400, Me.Top + 130
> End Sub
>
>
>
> "David" <dw85745***@earthlink.net> escribió en el mensaje
> news:O3oDkrSoJHA.6064@TK2MSFTNGP06.phx.gbl...
>> Thanks all for input and Eduardo for example.
>>
>> Eduardo, there is a way to create an new event for a VB form but
>> somewhat more complicated than subclassing.
>>
>> Will relook at subclassing as "best" option.
>>
>> David
>
>
Author
10 Mar 2009 11:03 AM
Tony Proctor
I guess subclassing would be the best route to go. However, trying to synchronise other controls/windows over the Form's caption sounds messy and doomed to failure in the end

I did knock up a tiny example that showed both a left-justified and right-justified string in the same non-MDI caption, and with no subclassing. With a bit more effort, I'm sure the "fixed overhead" constant of 1400 could be calculated properly but I have other work to do here

Maybe there's some mileage in trying to expand on it David, given that the example is so simple  :-)

    Tony Proctor

  "David" <dw85745***@earthlink.net> wrote in message news:uXQxQTPoJHA.504@TK2MSFTNGP06.phx.gbl...
  I have an MDIForm and want to put Date/Time on Right Side of MDIForm.Caption next to the buttons.  

  Any suggestions?

  Thanks

  David
Author
10 Mar 2009 11:05 AM
Tony Proctor
....sorry, told you I was in a hurry. Forgot to add the example code  :-(

Private Const CAP_LEFT As String = "Left bit"
Private Const CAP_RIGHT As String = "Right bit"

Private Sub SetCaption(sLeft As String, sRight As String)
Const FIX_OVH As Long = 1400
Dim lPad As Long, sPad As String

    lPad = Me.ScaleWidth - FIX_OVH - Me.TextWidth(sLeft) - Me.TextWidth(sRight)
    sPad = Space$(lPad \ Me.TextWidth(" "))
    Me.Caption = sLeft & sPad & sRight
End Sub

Private Sub Form_Load()
    SetCaption CAP_LEFT, CAP_RIGHT
End Sub

Private Sub Form_Resize()
    SetCaption CAP_LEFT, CAP_RIGHT
End Sub


    Tony Proctor
  "David" <dw85745***@earthlink.net> wrote in message news:uXQxQTPoJHA.504@TK2MSFTNGP06.phx.gbl...
  I have an MDIForm and want to put Date/Time on Right Side of MDIForm.Caption next to the buttons.  

  Any suggestions?

  Thanks

  David
Author
10 Mar 2009 11:39 AM
David
Mr. Proctor:

Thanks for the example and effort on my part.

David


"Tony Proctor" <tony_proctor@aimtechnology_NoMoreSPAM_.com> wrote in message
news:uFPboAXoJHA.1248@TK2MSFTNGP03.phx.gbl...
....sorry, told you I was in a hurry. Forgot to add the example code  :-(

Private Const CAP_LEFT As String = "Left bit"
Private Const CAP_RIGHT As String = "Right bit"

Private Sub SetCaption(sLeft As String, sRight As String)
Const FIX_OVH As Long = 1400
Dim lPad As Long, sPad As String

    lPad = Me.ScaleWidth - FIX_OVH - Me.TextWidth(sLeft) -
Me.TextWidth(sRight)
    sPad = Space$(lPad \ Me.TextWidth(" "))
    Me.Caption = sLeft & sPad & sRight
End Sub

Private Sub Form_Load()
    SetCaption CAP_LEFT, CAP_RIGHT
End Sub

Private Sub Form_Resize()
    SetCaption CAP_LEFT, CAP_RIGHT
End Sub


    Tony Proctor
  "David" <dw85745***@earthlink.net> wrote in message
news:uXQxQTPoJHA.504@TK2MSFTNGP06.phx.gbl...
  I have an MDIForm and want to put Date/Time on Right Side of
MDIForm.Caption next to the buttons.

  Any suggestions?

  Thanks

  David
Author
10 Mar 2009 9:59 PM
David
Mr. Proctor:

Your example works great for SDI -- not so well MDI since .TextWidth is not
a method of MDI.

Reworked you example (follows) but found that the RIghtBit string for some
reason gets hidden about 3/4 of the way toward the buttons
so something(??) is overlaying it after placement.even though using a flat
appearance.

Private Sub SetCaption(sLeft As String, sRight As String)
'Place a Left and Right String on the MDI TitleBar

   Dim lPad As Long
   Dim sPad As String
   Dim lngPixels As Long
   Dim lngTwips As Long

   '-------------------
   lngTwips = Me.ScaleWidth
   lngPixels = ConvertTwipsToPixels(lngTwips, 0)

'----------------------------------------------------------
'Applies to following code line:
     5 represents # of pixels in horizontal font.
'    Anything >5 brings string too far to left
'    Anything <5 hides string.
'    5 only hides part of string
'------------------------------------------------
   lngPixels = (lngPixels / 5)

   lPad = lngPixels - Len(sLeft) - Len(sRight)
   sPad = Space$(lPad \ Len(" "))
   Me.Caption = sLeft & sPad & sRight

End Sub



"Tony Proctor" <tony_proctor@aimtechnology_NoMoreSPAM_.com> wrote in message
news:uFPboAXoJHA.1248@TK2MSFTNGP03.phx.gbl...
....sorry, told you I was in a hurry. Forgot to add the example code  :-(

Private Const CAP_LEFT As String = "Left bit"
Private Const CAP_RIGHT As String = "Right bit"

Private Sub SetCaption(sLeft As String, sRight As String)
Const FIX_OVH As Long = 1400
Dim lPad As Long, sPad As String

    lPad = Me.ScaleWidth - FIX_OVH - Me.TextWidth(sLeft) -
Me.TextWidth(sRight)
    sPad = Space$(lPad \ Me.TextWidth(" "))
    Me.Caption = sLeft & sPad & sRight
End Sub

Private Sub Form_Load()
    SetCaption CAP_LEFT, CAP_RIGHT
End Sub

Private Sub Form_Resize()
    SetCaption CAP_LEFT, CAP_RIGHT
End Sub


    Tony Proctor
  "David" <dw85745***@earthlink.net> wrote in message
news:uXQxQTPoJHA.504@TK2MSFTNGP06.phx.gbl...
  I have an MDIForm and want to put Date/Time on Right Side of
MDIForm.Caption next to the buttons.

  Any suggestions?

  Thanks

  David
Author
11 Mar 2009 9:58 AM
Tony Proctor
Unless you're using a monospacing font then your calculation won't work
David. The thing about TextWidth is that it sizes each character
individually, and my calculation was then done in the scale units and not
simply characters

    Tony Proctor

Show quoteHide quote
"David" <dw85745***@earthlink.net> wrote in message
news:OpXy6tcoJHA.6132@TK2MSFTNGP06.phx.gbl...
> Mr. Proctor:
>
> Your example works great for SDI -- not so well MDI since .TextWidth is
> not a method of MDI.
>
> Reworked you example (follows) but found that the RIghtBit string for some
> reason gets hidden about 3/4 of the way toward the buttons
> so something(??) is overlaying it after placement.even though using a flat
> appearance.
>
> Private Sub SetCaption(sLeft As String, sRight As String)
> 'Place a Left and Right String on the MDI TitleBar
>
>   Dim lPad As Long
>   Dim sPad As String
>   Dim lngPixels As Long
>   Dim lngTwips As Long
>
>   '-------------------
>   lngTwips = Me.ScaleWidth
>   lngPixels = ConvertTwipsToPixels(lngTwips, 0)
>
> '----------------------------------------------------------
> 'Applies to following code line:
>     5 represents # of pixels in horizontal font.
> '    Anything >5 brings string too far to left
> '    Anything <5 hides string.
> '    5 only hides part of string
> '------------------------------------------------
>   lngPixels = (lngPixels / 5)
>
>   lPad = lngPixels - Len(sLeft) - Len(sRight)
>   sPad = Space$(lPad \ Len(" "))
>   Me.Caption = sLeft & sPad & sRight
>
> End Sub
>
>
>
> "Tony Proctor" <tony_proctor@aimtechnology_NoMoreSPAM_.com> wrote in
> message news:uFPboAXoJHA.1248@TK2MSFTNGP03.phx.gbl...
> ...sorry, told you I was in a hurry. Forgot to add the example code  :-(
>
> Private Const CAP_LEFT As String = "Left bit"
> Private Const CAP_RIGHT As String = "Right bit"
>
> Private Sub SetCaption(sLeft As String, sRight As String)
> Const FIX_OVH As Long = 1400
> Dim lPad As Long, sPad As String
>
>    lPad = Me.ScaleWidth - FIX_OVH - Me.TextWidth(sLeft) -
> Me.TextWidth(sRight)
>    sPad = Space$(lPad \ Me.TextWidth(" "))
>    Me.Caption = sLeft & sPad & sRight
> End Sub
>
> Private Sub Form_Load()
>    SetCaption CAP_LEFT, CAP_RIGHT
> End Sub
>
> Private Sub Form_Resize()
>    SetCaption CAP_LEFT, CAP_RIGHT
> End Sub
>
>
>    Tony Proctor
>  "David" <dw85745***@earthlink.net> wrote in message
> news:uXQxQTPoJHA.504@TK2MSFTNGP06.phx.gbl...
>  I have an MDIForm and want to put Date/Time on Right Side of
> MDIForm.Caption next to the buttons.
>
>  Any suggestions?
>
>  Thanks
>
>  David
>
>
>
>
>
>
>
>
>
>
>
>
>
>
Author
11 Mar 2009 10:36 AM
Mike Williams
"David" <dw85745***@earthlink.net> wrote in message
news:OpXy6tcoJHA.6132@TK2MSFTNGP06.phx.gbl...

> Mr. Proctor: Your example works great for SDI -- not so
> well MDI since .TextWidth is not a method of MDI.

There may be other ways of doing this but the first thing I would suggest is
that you create a memory DC (CreateCompatibleDC) and create a suitable font
for it (CreateFontIndirect) and assign the font to the DC (SelectObject).
You'll need to ensure that the font you create is the same as the font used
by the system for its Caption bar titles (there is a way of determing this
which I don't know off hand, but which I'm sure you'll easily discover, and
you'll need to do it because the font name and size may be quite different
to the font used by the Form and may be different on different systems). You
can then use GetTextExtent32 on the DC you created to get the length in
pixels of the space character and your two strings of text. You'll need to
delete the font and the DC when the Form unloads (DeleteObject).

> . . . found that the RIghtBit string for some reason gets hidden
> about 3/4 of the way toward the buttons so something(??) is
> overlaying it after placement.even though using a flat appearance.

Not sure exactly what you mean by that (although I think I know what you
mean?) but offhand I can't think of a reason for it, although one might
spring to mind if I find the time to knock up an example. In the meantime,
and as Tony has already said, the fixed constant of 1400 (twips) needs
replacing with the correct value, which is in fact system dependent.
Personally I would perform all calculations using pixels, which are in most
cases the native units used by Windows when it draws stuff. You can get the
width of each individual button on the task bar (which may be different on
different systems) using GetSystemMetrics with the parameter SM_CXSIZE (30).

Before you do any of these things you really need to go back to using the
code provided by Tony rather than your own modified version. Just use Tony's
version, but modify it so that it uses GetTextEntent32 (as mentioned above)
instead of TextWidth and so that it uses a calculated value (4 times the
value returned by the GetSystemMetrics call mentioned above if there are
four button on the bar (including the icon at the left). Make sure you are
using pixels throughout as the units of measurement. It'll make things much
easier.

Mike
Author
11 Mar 2009 5:04 PM
Ivar
I did look at this, But couldn't find the easy answer.
There seems to be two different setting that can be used for the title bar,
but they are always the same. adjusting one does the other and vice verser,
so you only need to worry about 1 of em.
The best way to get the font details of the TitleBar is to use
SystemParametersInfo with SPI_GETNONCLIENTMETRICS as the first parameter and
a NONCLIENTMETRICS structure as the third param (Second and forth being
zero)
The bit that stumped me was the count of the controlbar buttons- how many?
After a failed serch to determine how many buttons I gave up

There is some code below that will give info about the caption font.
Sorry, but hope this bit of info helps
Ivar


Option Explicit
Private Declare Function GetDeviceCaps Lib "gdi32" _
(ByVal hDC As Long, ByVal nIndex As Long) As Long
Private Declare Function SystemParametersInfo Lib _
"user32" Alias "SystemParametersInfoA" _
(ByVal uAction As Long, ByVal uParam As Long, _
lpvParam As NONCLIENTMETRICS, ByVal fuWinIni As Long) As Long

Private Const SPI_GETNONCLIENTMETRICS = 41
Private Const LOGPIXELSY = 90
Private Type LOGFONT
    Height As Long
    Width As Long
    Escapement As Long
    Orientation As Long
    Weight As Long
    Italic As Byte
    Underline As Byte
    StrikeOut As Byte
    CharSet As Byte
    OutPrecision As Byte
    ClipPrecision As Byte
    Quality As Byte
    PitchAndFamily As Byte
    FaceName As String * 32
    End Type


Private Type NONCLIENTMETRICS
    cbSize As Long
    iBorderWidth As Long
    iScrollWidth As Long
    iScrollHeight As Long
    iCaptionWidth As Long
    iCaptionHeight As Long
    lfCaptionFont As LOGFONT
    iSMCaptionWidth As Long
    iSMCaptionHeight As Long
    lfSMCaptionFont As LOGFONT
    iMenuWidth As Long
    iMenuHeight As Long
    lfMenuFont As LOGFONT
    lfStatusFont As LOGFONT
    lfMessageFont As LOGFONT
    End Type

Private Sub Form_Activate()
Dim ThisMetric As NONCLIENTMETRICS
Dim RetVal As Long
Dim CaptionLogFont As LOGFONT
Dim CF As New StdFont
ThisMetric.cbSize = Len(ThisMetric)
RetVal = SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, ThisMetric, 0)
CaptionLogFont = ThisMetric.lfCaptionFont
CF.Name = Trim(CaptionLogFont.FaceName)
CF.Size = Abs(CaptionLogFont.Height * 72 / _
GetDeviceCaps(Me.hDC, LOGPIXELSY))
CF.Bold = CaptionLogFont.Weight = 700
CF.Italic = CaptionLogFont.Italic <> 0
MsgBox "Name = " & CF.Name & vbCrLf & "Size = " & CF.Size & _
vbCrLf & "Bold = " & CF.Bold & vbCrLf & "Italic = " & CF.Italic
End Sub
Author
11 Mar 2009 6:39 PM
Mike Williams
"Ivar" <Ivar.ekstromer***@ntlworld.com> wrote in message
news:ZaStl.40897$6o3.35750@newsfe30.ams2...

> There is some code below that will give info about
> the caption font.

Thanks, Ivar. Just what the doctor ordered, and exactly what the OP needs
:-)

> The bit that stumped me was the count of the controlbar
> buttons- how many? After a failed serch to determine
> how many buttons I gave up

I was going to suggest GetWindowLong as follows:

    Dim z As Long, minBut As Boolean, maxBut As Boolean
    z = GetWindowLong(Me.hWnd, GWL_STYLE)
    minBut = (z And WS_MINIMIZEBOX) <> 0
    maxBut = (z And WS_MAXIMIZEBOX) <> 0

It does work, but (at least on Vista) both of the buttons are displayed
(although one of them is greyed out) if either of them is enabled (and if
either of them return True from the above code). This means that both
buttons are actually displayed (although one of them might be greyed out) if
one or both of them are enabled, and neither of them is displayed only if
they are both disabled. This can easily be accounted for with the above code
of course, but I'm wondering whether what I have described is the case on
all versions of Windows, or is it just Vista? My memory is not what it used
to be ;-)

Mike
Author
11 Mar 2009 10:05 PM
David
OK guys -- Will have to play with this some as not sure exactly where Ivar
and Mr. Williams are leaning in relationship to Mr. Proctors code.

As I previously indicated Mr. Proctors code works great for SDI but not MDI
because MDI does not have a TextWidth Method.

Created an MDI project.
Installed Ivar and Mr. Williams code.

===========
Ivar:

FWIW had to add GetDC as MDI only has an hWnd.
Executed code and returned some basic non-client font info as expected -- 
but not Font Height / Width which is part of LOGFONT.

I assume here that if I obtain the LOGFONT Width and multiply it times the
string length that this will equal the value returned by TextWidth?.

==================
Mr Williams.

Not sure why you want to get a control count.
Mr Proctors original code didn't take controls into account -- not that this
is not a bad idea as a MDI may be subclassed with other controls.

======================
Regarding the MDI title string only showing about 3/4 of the way on the
caption
..
My guess is only so many characters are available for the caption.  When a
string is set (MDIForm1.Caption =    ) and exceeds some length,  the last
part of the string does NOT show.   Since the MDI caption appears to be
gradient in color -- the gradient maybe overlaying the Caption if its length
exceeds the max length allocated for the string on the caption.







Show quoteHide quote
"David" <dw85745***@earthlink.net> wrote in message
news:OpXy6tcoJHA.6132@TK2MSFTNGP06.phx.gbl...
> Mr. Proctor:
>
> Your example works great for SDI -- not so well MDI since .TextWidth is
> not a method of MDI.
>
> Reworked you example (follows) but found that the RIghtBit string for some
> reason gets hidden about 3/4 of the way toward the buttons
> so something(??) is overlaying it after placement.even though using a flat
> appearance.
>
> Private Sub SetCaption(sLeft As String, sRight As String)
> 'Place a Left and Right String on the MDI TitleBar
>
>   Dim lPad As Long
>   Dim sPad As String
>   Dim lngPixels As Long
>   Dim lngTwips As Long
>
>   '-------------------
>   lngTwips = Me.ScaleWidth
>   lngPixels = ConvertTwipsToPixels(lngTwips, 0)
>
> '----------------------------------------------------------
> 'Applies to following code line:
>     5 represents # of pixels in horizontal font.
> '    Anything >5 brings string too far to left
> '    Anything <5 hides string.
> '    5 only hides part of string
> '------------------------------------------------
>   lngPixels = (lngPixels / 5)
>
>   lPad = lngPixels - Len(sLeft) - Len(sRight)
>   sPad = Space$(lPad \ Len(" "))
>   Me.Caption = sLeft & sPad & sRight
>
> End Sub
>
>
>
> "Tony Proctor" <tony_proctor@aimtechnology_NoMoreSPAM_.com> wrote in
> message news:uFPboAXoJHA.1248@TK2MSFTNGP03.phx.gbl...
> ...sorry, told you I was in a hurry. Forgot to add the example code  :-(
>
> Private Const CAP_LEFT As String = "Left bit"
> Private Const CAP_RIGHT As String = "Right bit"
>
> Private Sub SetCaption(sLeft As String, sRight As String)
> Const FIX_OVH As Long = 1400
> Dim lPad As Long, sPad As String
>
>    lPad = Me.ScaleWidth - FIX_OVH - Me.TextWidth(sLeft) -
> Me.TextWidth(sRight)
>    sPad = Space$(lPad \ Me.TextWidth(" "))
>    Me.Caption = sLeft & sPad & sRight
> End Sub
>
> Private Sub Form_Load()
>    SetCaption CAP_LEFT, CAP_RIGHT
> End Sub
>
> Private Sub Form_Resize()
>    SetCaption CAP_LEFT, CAP_RIGHT
> End Sub
>
>
>    Tony Proctor
>  "David" <dw85745***@earthlink.net> wrote in message
> news:uXQxQTPoJHA.504@TK2MSFTNGP06.phx.gbl...
>  I have an MDIForm and want to put Date/Time on Right Side of
> MDIForm.Caption next to the buttons.
>
>  Any suggestions?
>
>  Thanks
>
>  David
>
>
>
>
>
>
>
>
>
>
>
>
>
>
Author
11 Mar 2009 11:33 PM
Mike Williams
"David" <dw85745***@earthlink.net> wrote in message
news:Orv6vVpoJHA.3572@TK2MSFTNGP05.phx.gbl...

> OK guys -- Will have to play with this some as not sure
> exactly where Ivar and Mr. Williams are leaning in relationship
> to Mr. Proctors code.

Tony Proctor's code is just fine, as long as you replace the hard coded
value of 1400 twips (or whatever it was) which accounts for the space
occupied by the min, max and close buttons at the right, as Tony suggsted
himself. I suggested you should use his example, or at least use it as a
basis, rather than your own modification because Tony's code correctly reads
the actual length of the various strings of text, whether they be in a
proportionally spaced font or not, whereas your own modification does not.

> As I previously indicated Mr. Proctors code works great
> for SDI but not MDI because MDI does not have a
> TextWidth Method.

That's why I suggested that you create a DC and assign a font to it (the
same font name and size that your Form's Caption bar uses) so that you can
use the DC to check the actual pixel length of a string of text in that
font, instead of using the TextWidth method which, as you say, the MDI Form
does not possess. You could of course, as an alternative, have an otherwise
unused PictureBox (which does have a TextWidth method) somewhere in your
project and use that instead, but the memory DC method seems just 'cleaner'.

> FWIW had to add GetDC as MDI only has an hWnd.
> Executed code and returned some basic non-client font
> info as expected but not Font Height / Width which is
> part of LOGFONT.

Not sure what you mean there? Do you mean that you used the DC of the MDI
Form for the call to GetDeviceCaps in the code sample posted by Ivar? Is
that the code you are talking about here? If that is so then you don't
really need to do that. Ivar is using GetDeviceCaps as one method of
retrieving the systems 'pixels per inch' (which can be different on
different systems) purely so that the rest of his code can calculate the
point size of the font used by the Caption Bar from the pixel size that is
returned in LOGFONT structure so that he can print out the font details in
units that people most readily understand. But you don't actually need that
part of the code for your own purposes. The only part of the routine you
need yourself is the part up to and including the line:

    CaptionLogFont = ThisMetric.lfCaptionFont

At that point you have all the details of the font you require in the
CaptionLogFont structure, and you can pass that structure to the
CreateFontIndirect API function and the function will create a font in
accordance with the details held in the CaptionLogFont structure and it will
return the handle of the font it created. You then use the SelectObject API
to select that font (the handle returned by CreateFontIndirect) into the DC
you created with CreateCompatibleDC. You will then end up with a DC (the
memory DC you created) which effectively contains a font that is identical
in all ways to the font used by the system for the Form's Caption Bar . . .

> I assume here that if I obtain the LOGFONT Width and
> multiply it times the string length that this will equal the
> value returned by TextWidth? [1]

No. The Width item in the LOGFONT structure does not actually specify the
width of any character in the font. In order not to swamp you with detail I
won't go into it here, but the Width element in LOGFONT is just something
you can use when asking for a font (CreateFontIndirect) which can help the
system select the most suitable font for your requirements. In many cases it
is not used at all, and you will probably find it is set to zero. It is the
Height element which matters (typically, but not always, a negative value,
again for a reason I won't go into here to save 'overdoing' the
description). The Height (if it is negative, which you will almost certainly
find it is) specifies the point size of the font, but in pixels not points.
But you don't need to worry about any of that stuff for your purposes. Just
use the CaptionLogFont structure returned by Ivar's code in your call to
CreateFontIndirect as explained above.

> I assume here that if I obtain the LOGFONT Width and
> multiply it times the string length that this will equal the
> value returned by TextWidth? [2]

No. For starters the font in question is almost certainly a proportionally
spaced font, and the various characters have different pixel widths,
depending on the character ("M" is wider than "l" for example). Actually, as
explained above, the LOGFONT Width element is irrelevent here, and it is
probably zero anyway. You just perform the operations mentioned above and
you will end up with a memory DC (that you created with CreateCompatibleDC)
containing a font (that you created with CreateFontIndirect) which is
identical to the font used by your Form's Caption bars. Then, whenever you
want to find out the pixel length of a string of text you simply use the
GetTextExtentPoint32 API function, passing it the handle of your created DC,
the string you want to measure, the length of the string and a SIZE Type.
The actual pixel width of the entire string will be returned in the cx
element in the SIZE Type.

> Not sure why you want to get a control count.
> Mr Proctors original code didn't take controls into
> account -- not that this is not a bad idea as a MDI
> may be subclassed with other controls.

I wasn't getting a Control count. I was in fact getting a count of the
number of 'buttons' at the right edge of your caption bar (the min, max and
close buttons, if they are all shown) so that we can multiply their number
by the width of an indivisual 'button' (as determined by other parts of the
code) in order to replace the hard coded 1400 (or whatever it was) of Tony's
code with an actual calculated value. Getting the number of buttons is not
really important though, I think, because you will no doubt already know at
design time how many buttons are going to be on any Form you use this code
with. All you need to know is their widths.

If I had time I would knock up a complete example for you, but unfortunately
I'm running out of spare time at the moment and it will probably be better
anyway if I just explain things to you as best I can and allow you to
develop the actual code yourself.

Regarding the 'right hand part of the text' being missing on your MDI Forms
I'm not actually sure whether there is a limit to the character ot pixel
length of the caption. If I get time later I'll investigate that.

Mike
Author
12 Mar 2009 1:52 AM
David Youngblood
"David" <dw85745***@earthlink.net> wrote...
> OK guys -- Will have to play with this some as not sure exactly where Ivar
> and Mr. Williams are leaning in relationship to Mr. Proctors code.
>
> As I previously indicated Mr. Proctors code works great for SDI but not
> MDI because MDI does not have a TextWidth Method.
>
> Created an MDI project.

I think you are going to have problems with this method. The MDIForm's
maximum character count is 159 characters (160 including the null
character). A regular form will accept strings greater than 260, but will
only display the first 259 characters.

Try this, only 1 x is displayed on the right side and the returned caption
length is 159.
Private Sub MDIForm_Load()
    Me.WindowState = vbMaximized
    Me.Caption = "xxx" & Space(155) & "xxx"
    Debug.Print Len(Me.Caption)
End Sub

David
Author
12 Mar 2009 8:56 AM
Mike Williams
"David Youngblood" <d**@flash.net> wrote in message
news:%23DrWxUroJHA.1292@TK2MSFTNGP02.phx.gbl...

> The MDIForm's maximum character count is 159 characters
> (160 including the null character).

Thanks David. As I said at the end of my last response I wasn't sure about
the maximum permitted character count and I was going to check it, but now I
don't need to. So, it looks as though the OP is going to need to rethink
things and come up with a different method, perhaps placing a window in the
appropriate area and having it track the movement of the Form, or perhaps a
possibly better solution of using TextOut to draw the desired text at the
desired position directly onto the Form's Caption Bar, using GetWindowDC
rather than GetDC to obtain the DC into which he will need to draw. He'll
probably need to do a bit of subclassing though to redraw the text at the
appropriate time as the user is resizing because a simple Timer or Resize
event solution would cause flickering of the text under such conditions.
Might be worth looking into. Unless of course he would prefer to make things
very much easier for himself and place the date / time immediately after the
Caption (perhaps in brackets) rather than at the right hand side.

Mike
Author
12 Mar 2009 11:06 AM
David
Thanks for input Mr. Youngblood and Mr. Williams.

As previously posted, could tell caption string was being cut off ,just not
sure why or length.  Mr. Youngblood simple solution provides length.

Never thought something so simple would be such a hassle.
Oh Well -- Best Laid Plans.

Mr. Williams.

Your right, maybe a KISS method -- Date at end of string -- may be best /
simplest solution.

Will take a look at subclassing as a possible, otherwise go with KISS.




Show quoteHide quote
"David" <dw85745***@earthlink.net> wrote in message
news:Orv6vVpoJHA.3572@TK2MSFTNGP05.phx.gbl...
> OK guys -- Will have to play with this some as not sure exactly where Ivar
> and Mr. Williams are leaning in relationship to Mr. Proctors code.
>
> As I previously indicated Mr. Proctors code works great for SDI but not
> MDI because MDI does not have a TextWidth Method.
>
> Created an MDI project.
> Installed Ivar and Mr. Williams code.
>
> ===========
> Ivar:
>
> FWIW had to add GetDC as MDI only has an hWnd.
> Executed code and returned some basic non-client font info as expected -- 
> but not Font Height / Width which is part of LOGFONT.
>
> I assume here that if I obtain the LOGFONT Width and multiply it times the
> string length that this will equal the value returned by TextWidth?.
>
> ==================
> Mr Williams.
>
> Not sure why you want to get a control count.
> Mr Proctors original code didn't take controls into account -- not that
> this is not a bad idea as a MDI may be subclassed with other controls.
>
> ======================
> Regarding the MDI title string only showing about 3/4 of the way on the
> caption
> .
> My guess is only so many characters are available for the caption.  When a
> string is set (MDIForm1.Caption =    ) and exceeds some length,  the last
> part of the string does NOT show.   Since the MDI caption appears to be
> gradient in color -- the gradient maybe overlaying the Caption if its
> length exceeds the max length allocated for the string on the caption.
>
>
>
>
>
>
>
> "David" <dw85745***@earthlink.net> wrote in message
> news:OpXy6tcoJHA.6132@TK2MSFTNGP06.phx.gbl...
>> Mr. Proctor:
>>
>> Your example works great for SDI -- not so well MDI since .TextWidth is
>> not a method of MDI.
>>
>> Reworked you example (follows) but found that the RIghtBit string for
>> some reason gets hidden about 3/4 of the way toward the buttons
>> so something(??) is overlaying it after placement.even though using a
>> flat appearance.
>>
>> Private Sub SetCaption(sLeft As String, sRight As String)
>> 'Place a Left and Right String on the MDI TitleBar
>>
>>   Dim lPad As Long
>>   Dim sPad As String
>>   Dim lngPixels As Long
>>   Dim lngTwips As Long
>>
>>   '-------------------
>>   lngTwips = Me.ScaleWidth
>>   lngPixels = ConvertTwipsToPixels(lngTwips, 0)
>>
>> '----------------------------------------------------------
>> 'Applies to following code line:
>>     5 represents # of pixels in horizontal font.
>> '    Anything >5 brings string too far to left
>> '    Anything <5 hides string.
>> '    5 only hides part of string
>> '------------------------------------------------
>>   lngPixels = (lngPixels / 5)
>>
>>   lPad = lngPixels - Len(sLeft) - Len(sRight)
>>   sPad = Space$(lPad \ Len(" "))
>>   Me.Caption = sLeft & sPad & sRight
>>
>> End Sub
>>
>>
>>
>> "Tony Proctor" <tony_proctor@aimtechnology_NoMoreSPAM_.com> wrote in
>> message news:uFPboAXoJHA.1248@TK2MSFTNGP03.phx.gbl...
>> ...sorry, told you I was in a hurry. Forgot to add the example code  :-(
>>
>> Private Const CAP_LEFT As String = "Left bit"
>> Private Const CAP_RIGHT As String = "Right bit"
>>
>> Private Sub SetCaption(sLeft As String, sRight As String)
>> Const FIX_OVH As Long = 1400
>> Dim lPad As Long, sPad As String
>>
>>    lPad = Me.ScaleWidth - FIX_OVH - Me.TextWidth(sLeft) -
>> Me.TextWidth(sRight)
>>    sPad = Space$(lPad \ Me.TextWidth(" "))
>>    Me.Caption = sLeft & sPad & sRight
>> End Sub
>>
>> Private Sub Form_Load()
>>    SetCaption CAP_LEFT, CAP_RIGHT
>> End Sub
>>
>> Private Sub Form_Resize()
>>    SetCaption CAP_LEFT, CAP_RIGHT
>> End Sub
>>
>>
>>    Tony Proctor
>>  "David" <dw85745***@earthlink.net> wrote in message
>> news:uXQxQTPoJHA.504@TK2MSFTNGP06.phx.gbl...
>>  I have an MDIForm and want to put Date/Time on Right Side of
>> MDIForm.Caption next to the buttons.
>>
>>  Any suggestions?
>>
>>  Thanks
>>
>>  David
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>
>