Home All Groups Group Topic Archive Search About

How to best resize a form?

Author
29 Jan 2006 9:36 PM
Howard Kaikow
I've been using code like that below to resize forms.

However, I just noticed something that leads me to believe that there must
be a better way.

I usually run with a resolution of 1280 x 1024.

The Form I am using, created at 1280 x 1024, has a Height of 9210 and a
Width of 8910.
There's a Text box with Top = 7800, Left = 75, Height = 855, and Width =
6735.

If I run the Form, then, while the program is still running, change to 640 x
480, the code below gets the job done.

However, if I first change to 640 x 480, then run the program, the Text box
is not displayed.

Do I have to run MoveControls somewhere in the Load, or another, event to
get the proper result when the Form is first displayed?
If so, where?
If not, is there a better solution?

Here's the code.

In the Form, insert:

Private ControlPropertiesArray() As ControlProperties

Private Sub Form_Load()
    ReDim ControlPropertiesArray(0 To Me.Controls.Count - 1)
    InitializeControlPropertiesArray Me, ControlPropertiesArray()
End Sub

Private Sub Form_Resize()
    MoveControls Me, ControlPropertiesArray()
End Sub

In a module, insert:

    Public Type ControlProperties
        Width As Single
        Height As Single
        Top As Single
        Left As Single
    End Type

Public Sub InitializeControlPropertiesArray(AForm As Form,
ControlPropertiesArray() As ControlProperties)
    Dim ctrl As Control
    Dim i  As Integer
    Dim sngWidth As Single
    Dim sngHeight As Single

    On Error Resume Next
    With AForm
        sngWidth = .ScaleWidth
        sngHeight = .ScaleHeight
        For i = 0 To .Controls.Count - 1
            Set ctrl = .Controls(i)
            With ctrl
                If TypeOf ctrl Is Timer Then
        '        ElseIf TypeOf ctrl Is CommonDialog Then
                Else
                    With ControlPropertiesArray(i)
                        .Width = ctrl.Width / sngWidth
                        .Height = ctrl.Height / sngHeight
                        .Left = ctrl.Left / sngWidth
                        .Top = ctrl.Top / sngHeight
                    End With
                End If
            End With
        Next i
    End With
    On Error GoTo 0
    Set ctrl = Nothing
End Sub

Public Sub MoveControls(AForm As Form, ControlPropertiesArray() As
ControlProperties)
    Dim ctrl As Control
    Dim i  As Integer
    Dim sngWidth As Single
    Dim sngHeight As Single

    On Error Resume Next
    With AForm
        sngWidth = .ScaleWidth
        sngHeight = .ScaleHeight
        For i = 0 To .Controls.Count - 1
            Set ctrl = .Controls(i)
            If TypeOf ctrl Is Timer Then
    '        ElseIf TypeOf ctrl Is CommonDialog Then
            Else
                With ControlPropertiesArray(i)
                    ctrl.Move .Left * sngWidth, _
                        .Top * sngHeight, _
                        .Width * sngWidth, _
                        .Height * sngHeight
                End With
            End If
        Next i
    End With
    On Error GoTo 0
    Set ctrl = Nothing
End Sub

Author
29 Jan 2006 11:33 PM
Jim Edgar
Show quote Hide quote
"Howard Kaikow" <kai***@standards.com> wrote in message
news:ecdZYwRJGHA.2212@TK2MSFTNGP15.phx.gbl...
> I've been using code like that below to resize forms.
>
> However, I just noticed something that leads me to believe that there must
> be a better way.
>
> I usually run with a resolution of 1280 x 1024.
>
> The Form I am using, created at 1280 x 1024, has a Height of 9210 and a
> Width of 8910.
> There's a Text box with Top = 7800, Left = 75, Height = 855, and Width =
> 6735.
>
> If I run the Form, then, while the program is still running, change to 640
x
> 480, the code below gets the job done.
>
> However, if I first change to 640 x 480, then run the program, the Text
box
> is not displayed.
>
> Do I have to run MoveControls somewhere in the Load, or another, event to
> get the proper result when the Form is first displayed?
> If so, where?
> If not, is there a better solution?
>
> Here's the code.
>
> In the Form, insert:
>
> Private ControlPropertiesArray() As ControlProperties
>
> Private Sub Form_Load()
>     ReDim ControlPropertiesArray(0 To Me.Controls.Count - 1)
>     InitializeControlPropertiesArray Me, ControlPropertiesArray()
> End Sub
>
> Private Sub Form_Resize()
>     MoveControls Me, ControlPropertiesArray()
> End Sub
>
> In a module, insert:
>
>     Public Type ControlProperties
>         Width As Single
>         Height As Single
>         Top As Single
>         Left As Single
>     End Type
>
> Public Sub InitializeControlPropertiesArray(AForm As Form,
> ControlPropertiesArray() As ControlProperties)
>     Dim ctrl As Control
>     Dim i  As Integer
>     Dim sngWidth As Single
>     Dim sngHeight As Single
>
>     On Error Resume Next
>     With AForm
>         sngWidth = .ScaleWidth
>         sngHeight = .ScaleHeight
>         For i = 0 To .Controls.Count - 1
>             Set ctrl = .Controls(i)
>             With ctrl
>                 If TypeOf ctrl Is Timer Then
>         '        ElseIf TypeOf ctrl Is CommonDialog Then
>                 Else
>                     With ControlPropertiesArray(i)
>                         .Width = ctrl.Width / sngWidth
>                         .Height = ctrl.Height / sngHeight
>                         .Left = ctrl.Left / sngWidth
>                         .Top = ctrl.Top / sngHeight
>                     End With
>                 End If
>             End With
>         Next i
>     End With
>     On Error GoTo 0
>     Set ctrl = Nothing
> End Sub
>
> Public Sub MoveControls(AForm As Form, ControlPropertiesArray() As
> ControlProperties)
>     Dim ctrl As Control
>     Dim i  As Integer
>     Dim sngWidth As Single
>     Dim sngHeight As Single
>
>     On Error Resume Next
>     With AForm
>         sngWidth = .ScaleWidth
>         sngHeight = .ScaleHeight
>         For i = 0 To .Controls.Count - 1
>             Set ctrl = .Controls(i)
>             If TypeOf ctrl Is Timer Then
>     '        ElseIf TypeOf ctrl Is CommonDialog Then
>             Else
>                 With ControlPropertiesArray(i)
>                     ctrl.Move .Left * sngWidth, _
>                         .Top * sngHeight, _
>                         .Width * sngWidth, _
>                         .Height * sngHeight
>                 End With
>             End If
>         Next i
>     End With
>     On Error GoTo 0
>     Set ctrl = Nothing
> End Sub
>
>

I'm still confused about what you want.  The subject says you want the best
way to resize a form but the code you posted is moving controls around.  Do
you want to "know" when a user switches resolution so you can move the
controls?

Select Case Screen.Width / Screen.TwipsPerPixelX
    Case 800
    ...
End Select

Run the code inside a timer.

Are the forms modal and can the user resize them?  If you're trying to
resize and move the controls based on the form being resized then it's worth
searching Google of a good resize class.  You'll probably need to resize the
control fonts which a good resizer will do.  I use an old ocx from Apex as a
resizer but I don't think it's around anymore.

I hope this is of some help.

BTW - the form centering ideas you got from your first post are still valid.

Jim Edgar
Author
30 Jan 2006 12:11 AM
Michael C
"Jim Edgar" <djedgarRemoveT***@cox.net> wrote in message
news:%23ps4pxSJGHA.1424@TK2MSFTNGP12.phx.gbl...
> Select Case Screen.Width / Screen.TwipsPerPixelX
>    Case 800
>    ...
> End Select
>
> Run the code inside a timer.

Surely you jest?

Michael
Author
30 Jan 2006 11:00 AM
Dave
Show quote Hide quote
"Michael C" <mculley@NOSPAMoptushome.com.au> wrote in message
news:exSOgCTJGHA.3144@TK2MSFTNGP11.phx.gbl...
> "Jim Edgar" <djedgarRemoveT***@cox.net> wrote in message
> news:%23ps4pxSJGHA.1424@TK2MSFTNGP12.phx.gbl...
>> Select Case Screen.Width / Screen.TwipsPerPixelX
>>    Case 800
>>    ...
>> End Select
>>
>> Run the code inside a timer.
>
> Surely you jest?
>
> Michael

I have a horrible suspicion that he is serious, maybe he does not know about
the system-wide messages that Windows issues when things like screen
resolution get changed.

Yours
Dave O.
Author
31 Jan 2006 12:05 AM
Jim Edgar
Show quote Hide quote
"Michael C" <mculley@NOSPAMoptushome.com.au> wrote in message
news:exSOgCTJGHA.3144@TK2MSFTNGP11.phx.gbl...
> "Jim Edgar" <djedgarRemoveT***@cox.net> wrote in message
> news:%23ps4pxSJGHA.1424@TK2MSFTNGP12.phx.gbl...
> > Select Case Screen.Width / Screen.TwipsPerPixelX
> >    Case 800
> >    ...
> > End Select
> >
> > Run the code inside a timer.
>
> Surely you jest?
>
> Michael
>
>

Why not if you only want to be notified that the screen resolution has
changed?  You could also subclass to hook a system change notification or
use the SysInfo control for the notification but checking the screen
resolution every few seconds or minutes doesn't seem like it would break the
application.  Some guy named Dave also put in his two cents without offering
any code sample or offering a justification why it won't work.  What is the
best way for an application to be notified that the resolution has changed?

Jim Edgar
Author
31 Jan 2006 12:46 AM
Michael C
"Jim Edgar" <djedgarRemoveT***@cox.net> wrote in message
news:O6WNXofJGHA.964@tk2msftngp13.phx.gbl...
> Why not if you only want to be notified that the screen resolution has
> changed?  You could also subclass to hook a system change notification or
> use the SysInfo control for the notification but checking the screen
> resolution every few seconds or minutes doesn't seem like it would break
> the
> application.

It won't and it's probably not that big a problem. It might not create any
problems and the user will probably never know it's done this way. But it's
not the right way to do it. If this was the one and only thing you didn't do
the right way in your entire app then it wouldn't likely be a problem but if
keep doing things like this they build up and cause problems later.

> Some guy named Dave also put in his two cents without offering
> any code sample or offering a justification why it won't work.  What is
> the
> best way for an application to be notified that the resolution has
> changed?

I would use the system notification myself but the SysInfo control could be
ok.

Michael
Author
31 Jan 2006 2:32 AM
Jim Edgar
Show quote Hide quote
"Michael C" <mculley@NOSPAMoptushome.com.au> wrote in message
news:ODjCl6fJGHA.3904@TK2MSFTNGP10.phx.gbl...
> "Jim Edgar" <djedgarRemoveT***@cox.net> wrote in message
> news:O6WNXofJGHA.964@tk2msftngp13.phx.gbl...
> > Why not if you only want to be notified that the screen resolution has
> > changed?  You could also subclass to hook a system change notification
or
> > use the SysInfo control for the notification but checking the screen
> > resolution every few seconds or minutes doesn't seem like it would break
> > the
> > application.
>
> It won't and it's probably not that big a problem. It might not create any
> problems and the user will probably never know it's done this way. But
it's
> not the right way to do it. If this was the one and only thing you didn't
do
> the right way in your entire app then it wouldn't likely be a problem but
if
> keep doing things like this they build up and cause problems later.
>
> > Some guy named Dave also put in his two cents without offering
> > any code sample or offering a justification why it won't work.  What is
> > the
> > best way for an application to be notified that the resolution has
> > changed?
>
> I would use the system notification myself but the SysInfo control could
be
> ok.
>
> Michael
>
>

Thanks for the response.  All of my apps are "in house" and I have complete
control over source code so using the code I posted is not entirely out of
the possibility.  That said, I can't imagine a scenario when I would need
the app to respond to the user changing the screen resolution.  It's just
how I interpreted the OP's original request.  Thanks again.

Jim Edgar
Author
15 Feb 2006 9:21 PM
Mike Williams
"Michael C" <mculley@NOSPAMoptushome.com.au> wrote in message
news:exSOgCTJGHA.3144@TK2MSFTNGP11.phx.gbl...

> Surely you jest?
> Michael

Hey! That's my phrase! I was the first to use that phrase on the newsgroup!
If you want to use it in your own posts your gonna have to pay me 0.001
cents a time ;-)

Mike
Author
15 Feb 2006 9:32 PM
Mike Williams
"Mike Williams" <M***@WhiskyAndCoke.com> wrote in message
news:u1Kf1WnMGHA.1040@TK2MSFTNGP10.phx.gbl...

> Hey! That's my phrase! I was the first to use that phrase on the
> newsgroup! If you want to use it in your own posts your gonna
> have to pay me 0.001 cents a time ;-)

Oops! My mistake! I've just "Googled" the VB groups and I first used that
phrase on clbvm in May 2002, whereas Stefan Berglund used the phrase on this
very group in April 2001! Bugger! So it's not my 0.001 cents after all ;-)

Mike
Author
16 Feb 2006 1:52 AM
Bob O`Bob
Mike Williams wrote:
> "Mike Williams" <M***@WhiskyAndCoke.com> wrote in message
> news:u1Kf1WnMGHA.1040@TK2MSFTNGP10.phx.gbl...
>
>> Hey! That's my phrase! I was the first to use that phrase on the
>> newsgroup! If you want to use it in your own posts your gonna
>> have to pay me 0.001 cents a time ;-)
>
> Oops! My mistake! I've just "Googled" the VB groups and I first used
> that phrase on clbvm in May 2002, whereas Stefan Berglund used the
> phrase on this very group in April 2001! Bugger! So it's not my 0.001
> cents after all ;-)


and anyway, the movie "Airplane" came out many years before Microsoft
realized there was an Internet.




    Bob
--
Author
15 Feb 2006 9:48 PM
Rick Rothstein [MVP - Visual Basic]
> > Surely you jest?
> > Michael
>
> Hey! That's my phrase! I was the first to use that phrase
> on the newsgroup! If you want to use it in your own posts
> your gonna have to pay me 0.001 cents a time ;-)

Surely you jest?  <g>

Rick
Author
15 Feb 2006 10:54 PM
RonW
On Wed, 15 Feb 2006 16:48:25 -0500, "Rick Rothstein [MVP - Visual Basic]"
<rickNOSPAMnews@NOSPAMcomcast.net> wrote:

>> > Surely you jest?
>> > Michael
>>
>> Hey! That's my phrase! I was the first to use that phrase
>> on the newsgroup! If you want to use it in your own posts
>> your gonna have to pay me 0.001 cents a time ;-)
>
>Surely you jest?  <g>
>
>Rick
>

No; And don't call me "Shirley."

Well *somebody* had to post it!

RW
Author
16 Feb 2006 8:25 AM
Michael C
"Mike Williams" <M***@WhiskyAndCoke.com> wrote in message
news:u1Kf1WnMGHA.1040@TK2MSFTNGP10.phx.gbl...
> Hey! That's my phrase! I was the first to use that phrase on the
> newsgroup! If you want to use it in your own posts your gonna have to pay
> me 0.001 cents a time ;-)

Sh*t, I've had a few conversations with you lately, maybe that's where I
picked it up. Anyway, cheque's in the mail, go out to your letter box and
wait ;-)

Michael
Author
30 Jan 2006 2:45 AM
Larry Serflaten
Show quote Hide quote
"Howard Kaikow" <kai***@standards.com> wrote
> I've been using code like that below to resize forms.
....
>
> Do I have to run MoveControls somewhere in the Load, or another, event to
> get the proper result when the Form is first displayed?
> If so, where?
> If not, is there a better solution?

> Public Sub InitializeControlPropertiesArray(AForm As Form,
> ControlPropertiesArray() As ControlProperties)

>     On Error Resume Next
>     With AForm
>         sngWidth = .ScaleWidth
>         sngHeight = .ScaleHeight


Change to:

        sngWidth = 8910
        sngHeight = 9210


Windows limits the size a form can be, it has changed the size even before
the first form event, and before the first Resize, so your textbox is actually
outside the form when you do your initialization.  Subsequent calls to move
it, also leave it outside the form.

Your controls were set with a specific form size, so when you initialize your
array, you have to use that size, and not the new size Windows has changed
your form to....

Make sense?
LFS
Author
30 Jan 2006 12:23 PM
Howard Kaikow
The solution appears to be to add

Private Sub Form_Initialize()
    MoveControls Me, ControlPropertiesArray()
End Sub
Author
30 Jan 2006 12:46 PM
Larry Serflaten
"Howard Kaikow" <kai***@standards.com> wrote
> The solution appears to be to add
>
> Private Sub Form_Initialize()
>     MoveControls Me, ControlPropertiesArray()
> End Sub


FWIW:  That would not work in VB5.
From  what I saw the events were:

Form_Load
Form_Initialize
From_Resize

But Windows had already changed the size of the form prior to
the Load event, so again, that left the textbox outside the form
and that is where it got placed during initialization.

LFS
Author
30 Jan 2006 3:29 PM
Howard Kaikow
"Larry Serflaten" <serfla***@usinternet.com> wrote in message
news:%23K9WqsZJGHA.2040@TK2MSFTNGP14.phx.gbl...
> FWIW:  That would not work in VB5.
> From  what I saw the events were:
>
> Form_Load
> Form_Initialize
> From_Resize
>
> But Windows had already changed the size of the form prior to
> the Load event, so again, that left the textbox outside the form
> and that is where it got placed during initialization.

In VB6, the order is

Initialize
Load
Resize

However, the issue could be due to how I've implemented the code.

My question was based on my implementation of the code presented in Gary
Cornell's VB 6 From the Ground Up.
Author
30 Jan 2006 6:08 PM
Larry Serflaten
"Howard Kaikow" <kai***@standards.com> wrote

> In VB6, the order is
>
> Initialize
> Load
> Resize
>
> However, the issue could be due to how I've implemented the code.

My mistake, I was printing the size properties in each of those events,
something like:

Private Sub Form_Load()
Debug.Print "Load", Width, Height
End Sub

And that altered the order of the events.  If I didn't access Width and
Height, it went as you described.

Good luck on your solution!
LFS
Author
30 Jan 2006 3:38 PM
Howard Kaikow
Dag nab it, ignore my previous post, I left out some stuff.

In VB6, the order is

Initialize
Load
Resize

However, the issue could be due to how I've implemented the code.

My question was based on my implementation of the code presented on pages
552-556 of Gary
Cornell's VB 6 From the Ground Up.

I am also trying to implement the algorithm at
http://www.vb-helper.com/howto_stretch_controls.html.

Neither is a complete solution.
Author
30 Jan 2006 9:59 PM
Michael C
"Howard Kaikow" <kai***@standards.com> wrote in message
news:eNKS4fZJGHA.2696@TK2MSFTNGP14.phx.gbl...
> The solution appears to be to add
>
> Private Sub Form_Initialize()
>    MoveControls Me, ControlPropertiesArray()
> End Sub

Code like this should not go in Form_Initialize.

Show quoteHide quote
>
>
>
Author
30 Jan 2006 11:07 PM
Howard Kaikow
"Michael C" <mculley@NOSPAMoptushome.com.au> wrote in message
news:%23NRNFdeJGHA.2300@TK2MSFTNGP15.phx.gbl...
> "Howard Kaikow" <kai***@standards.com> wrote in message
> news:eNKS4fZJGHA.2696@TK2MSFTNGP14.phx.gbl...
> > The solution appears to be to add
> >
> > Private Sub Form_Initialize()
> >    MoveControls Me, ControlPropertiesArray()
> > End Sub
>
> Code like this should not go in Form_Initialize.

Perhaps, but for the code I posted, I've not yet found another way around
the problem I described.

However, for my alternative implementation, based on the code to which I
pointed at V BHelper, the problem does not seem to occur.

I've got to analyze both to see what's different.
In the interim, I'm using a compiler constant to select which method I use,
which, for the moment, avoids using the Initialize event.



Show quoteHide quote
>
> >
> >
> >
>
>
Author
31 Jan 2006 12:15 AM
Michael C
"Howard Kaikow" <kai***@standards.com> wrote in message
news:%23A7t2HfJGHA.424@TK2MSFTNGP12.phx.gbl...
> Perhaps, but for the code I posted, I've not yet found another way around
> the problem I described.
>
> However, for my alternative implementation, based on the code to which I
> pointed at V BHelper, the problem does not seem to occur.
>
> I've got to analyze both to see what's different.
> In the interim, I'm using a compiler constant to select which method I
> use,
> which, for the moment, avoids using the Initialize event.

I don't fully understand the problem but it looks to me like you've got
yourself in a huge twist somehow. You should be able to just put all your
code in Form_Resize to move controls on the form where ever you require and
that's it. Code in Form_Load or INitialize should not be required.

Michael
Author
31 Jan 2006 5:26 AM
Howard Kaikow
"Michael C" <mculley@NOSPAMoptushome.com.au> wrote in message
news:uHQIRpfJGHA.2708@tk2msftngp13.phx.gbl...
> I don't fully understand the problem but it looks to me like you've got
> yourself in a huge twist somehow. You should be able to just put all your
> code in Form_Resize to move controls on the form where ever you require
and
> that's it. Code in Form_Load or INitialize should not be required.

Take a look at both the VB Helper article and the pages in Gary Cornell's
book.
The results are more accurate if one saves the original settings for each
control.
Author
30 Jan 2006 4:45 PM
Mike Williams
"Howard Kaikow" <kai***@standards.com> wrote in message
news:ecdZYwRJGHA.2212@TK2MSFTNGP15.phx.gbl...

> Do I have to run MoveControls somewhere in the Load,
> or another, event to get the proper result when the Form
> is first displayed? If so, where? If not, is there a better solution?

I haven't looked at your code in this thread because you appear to have
already had the answer to your question from others, but I just thought I'd
mention that there are other things besides desktop size (800 x 600, 1024 x
768, etc, etc) that you need to take into account. Now that you've
apparently got your size and position code running as you want it, do
yourself a favour and set your machine to a different "dots per inch"
setting than you are currently using and run your compiled exe again. For
example, if you're currently running at the most common setting of 96 pixels
per inch then change to the next most common setting of 120 pixels per inch
and see how your app behaves.

Mike
Author
30 Jan 2006 7:30 PM
Howard Kaikow
Actually, the current code is really not complete.

Although the example from VB Helper seems to handle fonts, there is still a
point at which things don't fit nicely, if at all. It would be nice if there
was a pointer to a more general algorithm.

Not to ention, certain controls won't resize, e.g. it is not possible to
change the size of a ComboBox, according to KB article q182070.

A more complete example is supposed to be in Rod Stephens book Custom
Control Libray, but the book is out of print.

I guess that I'll have to live with what I have, until I learn more.
Author
30 Jan 2006 8:39 PM
Mike Williams
"Howard Kaikow" <kai***@standards.com> wrote in message
news:eNm$lOdJGHA.3260@TK2MSFTNGP11.phx.gbl...

> Although the example from VB Helper seems to handle fonts, there
> is still a point at which things don't fit nicely, if at all. It would be
> nice
> if there was a pointer to a more general algorithm.

There really isn't "general algorithm". For example, it is highly unusual
for a window and all its contents to be resized in the same way. In most
cases certain elements of the design remain at a fixed size while other
elements do not, and the user is often allowed to make decisions that
themselves have an effect on these things. It is entirely up to the designer
of the app to decide which specific methods best fit his own needs, and this
can vary from app to app.

Mike
Author
30 Jan 2006 11:03 PM
Howard Kaikow
"Mike Williams" <M***@WhiskyAndCoke.com> wrote in message
news:u822M1dJGHA.2040@TK2MSFTNGP14.phx.gbl...

> There really isn't "general algorithm". For example, it is highly unusual
> for a window and all its contents to be resized in the same way. In most
> cases certain elements of the design remain at a fixed size while other
> elements do not, and the user is often allowed to make decisions that
> themselves have an effect on these things. It is entirely up to the
designer
> of the app to decide which specific methods best fit his own needs, and
this
> can vary from app to app.

The Form is resizeable.
Author
31 Jan 2006 9:53 AM
Mike Williams
"Howard Kaikow" <kai***@standards.com> wrote in message
news:eGM7QFfJGHA.2036@TK2MSFTNGP14.phx.gbl...

> The Form is resizeable.

I'm sure it is, but that doesn't necessarily mean that *everything on it*
should change its size and position as the user changes the size of the
Form. Most apps don't behave in that way. Usually there are some elements
that change their size (and position) and others that remain fixed in size
and position but either get "clipped" or drop themselves into a scrollable
container if the Form becomes to small for them to fit (have a look at MS
Word and ACDSee and Corel Draw and Adobe Photoshop and other apps). In MS
Word try changing the "View" and you'll see different things happen
(depending on the user's settings). Other apps behave in a constant way
depending on the programmer's settings. That's what I meant when I said
"there is no such thing as a general algorithm". Many of the decisions as to
how an app should behave when the user resizes it are down to the
programmer, and they won't necessarily be the same for every app that
programmer writes.

Mike