Share via

Control width of notepad window that is created in Word VBA?

Anonymous
2017-09-21T14:12:47+00:00

Using the following code to paste debugging information to a text window. The debug info is many rows, but only a few chars per row. I am repeatedly narrowing the width of the window each time I run the code, so I can leave it visible while maximizing the rest of my screen space.  Is there any way to add code that will auto-adjust the width of the notepad window, to a fixed width? (I can play around to find the right width, just need to know if this is possible and how to accomplish it).

VBA recognizes (autocapitalizes) the Width keyword, but when run gives "Compile error: Invalid qualifier"

Sub Write2Notepad(MyStr As String)

    Dim hWnd As Long

    Dim chWnd As Long

    Dim s As String

     'start Notepad

    Call Shell("NOTEPAD.EXE", vbNormalFocus)

    hWnd = FindWindow("Notepad", vbNullString)

     'Find a control window handle... in Notepad, there's the main Textbox that you want.

    chWnd = FindWindowEx(hWnd, ByVal 0&, vbNullString, vbNullString)

    SendMessage chWnd, WM_SETTEXT, ByVal 0&, MyStr

    'chWnd.Width = 100 '<-- doesn't work

    'hWnd.Width = 100 '<-- doesn't work

End Sub

Sub TestNotepadWidth

    Write2Notepad("A47J12")

EndSub

Moved from:  Office / Word / Windows other / Office 2016

Microsoft 365 and Office | Word | For home | Windows

Locked Question. This question was migrated from the Microsoft Support Community. You can vote on whether it's helpful, but you can't add comments or replies or follow the question.

0 comments No comments

Answer accepted by question author

  1. Jay Freedman 207.6K Reputation points Volunteer Moderator
    2017-09-21T19:55:00+00:00

    I can set the size of the Notepad window with this code:

    Declare Function SetWindowPos& Lib "user32" (ByVal hwnd As Long, ByVal _

        hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, _

        ByVal cy As Long, ByVal wFlags As Long)

    Const HWND_TOP = 0&

    Const SWP_NOMOVE = &H2

    Const SWP_NOZORDER = &H4

    Const SWP_SHOWWINDOW = &H40

    ...

        SetWindowPos hwnd, HWND_TOP, 0&, 0&, 100&, 600&, _

             SWP_NOMOVE + SWP_NOZORDER + SWP_SHOWWINDOW

    What I can't get to work is the SendMessage call. Instead of the passed MyStr parameter, the Notepad window shows three random characters. I also tried using the SetWindowText function instead of SendMessage, but that failed because the Word macro and the Notepad window are in separate processes. The MSDN documentation for SetWindowText says "To set the text of a control in another process, send the WM_SETTEXT message directly instead of calling SetWindowText."

    Was this answer helpful?

    0 comments No comments

3 additional answers

Sort by: Most helpful
  1. Anonymous
    2017-09-25T10:01:49+00:00

    I am seeing the correct MyString variable in the notepad window.

    It may be a version difference between us? I'm using Excel x32 on Win7x64. I don't recall changing any references at the start of this project, but here is what is currently assigned:

    I'll pick up a copy of the API book, that looks very handy :)

    Thank you!

    Was this answer helpful?

    0 comments No comments
  2. Jay Freedman 207.6K Reputation points Volunteer Moderator
    2017-09-22T16:24:35+00:00

    If you expect to do any more work with API functions, it's worth buying a used copy of Dan Appleman's Visual Basic Programmer's Guide to the Win32 API. It's enormous (1500+ pages, weighing about 5 lb), and last revised 18 years ago, but it's indispensable. Most of the API functions are usable in VBA through Declare statements, and Appleman describes better than the online documentation what they do. If you buy a used copy, make sure you get the CD that should be in the back cover pocket; it has example code and additional documentation.

    It's typical that there's no direct way to say "leave the cy argument unchanged but change the cx". (There is a flag, SWP_NOSIZE, that says to leave both cx and cy unchanged, but that's not what we want here.) What you'd have to do is call the API function GetWindowRect, which returns a pointer to a RECT structure containing the coordinates of the top left and bottom right corners of the hwnd window; then subtract the y value of the top left from the y value of the bottom right to get the current value of cy, and pass that to SetWindowPos (ouch!).

    Are you seeing the correct value of the MyString variable ("A47J12") in the Notepad window? I couldn't get that to work.

    Was this answer helpful?

    0 comments No comments
  3. Anonymous
    2017-09-22T10:55:14+00:00

    Jay, thank you. The other APIs below are ones I had just copy/pasted from the web, but I haven't used windows API enough to know what they mean.

    Based on searching the web to learn more about SetWindowPos, I got the following code working. The only thing I wish I could change is to leave the original height by default rather than having to set it, but I'm not sure how to do that :)

    Since I do have the narrower width, I'm going to mark this question as answered. Thanks again!

    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

     'Finds a window with the name, returns the handle.

    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Integer, ByVal lParam As Any) As Long

     'Sends a specified message to the window handle that you give it.

    Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long

     'Gets a controls window handle. The form window handle must be specified to get a decent control.

    Const WM_SETTEXT As Long = &HC

     'Sets the text of this control.

    Option Base 1

    '----------------------------------------------------------------------------------

    '--- added for the code to narrow the notepad window size when reviewing bookmark names --------

    '----------------------------------------------------------------------------------

    'Private Declare Function FindWindow Lib "user32.dll" Alias _

    '"FindWindowA" (ByVal lpClassName As String, _

    'ByVal lpWindowName As String) As Long

    Private Declare Function SetParent Lib "user32.dll" _

    (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long

    Private Declare Function SetWindowPos Lib "user32.dll" _

    (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, _

    ByVal x As Long, ByVal y As Long, ByVal cx As Long, _

    ByVal cy As Long, ByVal wFlags As Long) As Long

    'Private Declare Function GetDesktopWindow Lib "user32" () As Long

    Private Const SWP_NOZORDER As Long = &H4

    Private Const SWP_SHOWWINDOW As Long = &H40

    Const HWND_TOP = 0&

    Const SWP_NOMOVE = &H2

    Private Sub textsdfs()

    Write2Notepad ("A47J12")

    End Sub

    Sub Write2Notepad(MyStr As String)

        Dim hwnd As Long

        Dim chWnd As Long

        Dim s As String

         'start Notepad

        Call Shell("NOTEPAD.EXE", vbNormalFocus)

        hwnd = FindWindow("Notepad", vbNullString)

         'Find a control window handle... in Notepad, there's the main Textbox that you want.

        chWnd = FindWindowEx(hwnd, ByVal 0&, vbNullString, vbNullString)

        SendMessage chWnd, WM_SETTEXT, ByVal 0&, MyStr

        'hWnd.Width = 100

         'SetWindowPos hwnd ', 0&, 0&, 0&, 100&, 600

        'Resize the Window

        SetWindowPos hwnd, 0, 0&, 0&, 400&, _

        900&, SWP_NOZORDER Or SWP_SHOWWINDOW

    End Sub

    Was this answer helpful?

    0 comments No comments