Solved

Inter-related Windows !!

Posted on 2006-06-23
8
322 Views
Last Modified: 2010-04-07
Hi all,

I want to have a NotePad application stick to my form so if I move the form, the Notepad app will move with it and if I minimise the form it will also minimise.

I am not sure what Window Style I should set for the notepad to behave like that.

I have tried WS_CHILD but didn't really work.

Anybody on this one.

Thank you.
0
Comment
Question by:RAFAAJ
  • 4
  • 3
8 Comments
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
It would be similar to the code here:
http://www.experts-exchange.com/Programming/Programming_Languages/Visual_Basic/Q_21205433.html

But instead of moving Form2, you would move your NotePad window using the SetWindowPos() API.
0
 

Author Comment

by:RAFAAJ
Comment Utility
Thanks Idle_Mind,

I can't seem to Subclass NotPad !! It's very strange !!

I can subclass other application windows but not NotePad !!!

Here is what I have in the Form_Load event. ( Notice the lPrevProc which returns 0 indicating that Subclassing has failed !)


'in the Form Module

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

Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" _
    (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal msg As Long, _
    ByVal wParam As Long, ByVal lParam 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 Const GWL_WNDPROC As Long = (-4)
Private Const WM_MOVING = &H216
Private Const WM_SIZING = &H214

Private lngHwnd As Long
Private lPrevProc As Long



Private Sub UserForm_Initialize()

    Shell "NOTEPAD.EXE", 1
   
    lngHwnd = FindWindow("NotePad", vbNullString)
   
    MsgBox lngHwnd   ' \\ this returns a valid Hwnd #
   
     lPrevProc = SetWindowLong(lngHwnd, GWL_WNDPROC, AddressOf HookProc)
   
    MsgBox lPrevProc   ' \\ this returns 0 !! meaning Subclassing failed !! Why ??!!!


End Sub


The HookProc resides in a Basic Module .


Can you spot what I might be doing wrong ?!! or are some applications impossible to subclass ?!

Thanks.
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
Don't subclass NotePad.  VB can't subclass forms in an external application.

Subclass the VB form instead.

Then when it receives the WM_MOVING or WM_SIZING msgs, move the NotePad window accordingly using SetWindowPos() or another window moving/positioning API.
0
 

Author Comment

by:RAFAAJ
Comment Utility
Oops !  That is True ...I knew that but I somehow forgot !

Basically, what I need to do is prevent the NotePad application to be close by the user while the Form is open.

I thought about subclassing NotePad but as you said that Can't be done because it is in a foreign Process,

An alternative will probably be to change the relevant NotePad Window Styles so it can't be closed while the form is loaded  and restore it defaults upon closing the Form.

Can you think of a better alternative  for achieving the above ?

Thanks for your help.

0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 85

Accepted Solution

by:
Mike Tomlinson earned 125 total points
Comment Utility
Here is how to disable the X (close button) in the top right and also how to remove the File --> Exit item in the menu system for Notepad.

Option Explicit

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

Private Declare Function DrawMenuBar Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetMenuItemCount Lib "user32" (ByVal hMenu As Long) As Long
Private Declare Function GetSystemMenu Lib "user32" (ByVal hwnd As Long, ByVal bRevert As Long) As Long
Private Declare Function RemoveMenu Lib "user32" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long) As Long
 
Private Declare Function GetMenu Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetSubMenu Lib "user32" (ByVal hMenu As Long, ByVal nPos As Long) As Long
 
Private Const MF_BYPOSITION = &H400
Private Const MF_REMOVE = &H1000
 
Private Sub Command1_Click()
    Dim noteWnd As Long
    noteWnd = FindWindow("Notepad", vbNullString)
    If noteWnd <> 0 Then
        DisableX noteWnd
        RemoveNotepadFileExit noteWnd
    End If
End Sub

Private Sub DisableX(ByVal hwnd As Long)
    Dim hMenu As Long
    Dim lItemCount As Long
    hMenu = GetSystemMenu(hwnd, 0)
    If hMenu Then
        lItemCount = GetMenuItemCount(hMenu)
        Call RemoveMenu(hMenu, lItemCount - 1, MF_REMOVE Or MF_BYPOSITION)
        Call RemoveMenu(hMenu, lItemCount - 2, MF_REMOVE Or MF_BYPOSITION)
        Call DrawMenuBar(hwnd)
    End If
End Sub

Private Sub RemoveNotepadFileExit(ByVal hwnd As Long)
    Dim hMenu As Long
    hMenu = GetMenu(hwnd)
    If hMenu Then
        Dim hSubMenu As Long
        hSubMenu = GetSubMenu(hMenu, 0)
        If hSubMenu Then
            Call RemoveMenu(hSubMenu, 8, MF_REMOVE Or MF_BYPOSITION) ' Exit
            Call RemoveMenu(hSubMenu, 7, MF_REMOVE Or MF_BYPOSITION) ' Seperator
            Call DrawMenuBar(hwnd)
        End If
    End If
End Sub
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
Pretty sure you can't undo these changes though so you would need to close Notepad yourself using SendMessage():

Option Explicit

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
 
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

Private Const WM_CLOSE = &H10

Private Sub Command1_Click()
    Dim noteWnd As Long
    noteWnd = FindWindow("Notepad", vbNullString)
    If noteWnd <> 0 Then
        SendMessage noteWnd, WM_CLOSE, 0, 0
    End If
End Sub

0
 

Author Comment

by:RAFAAJ
Comment Utility
Thanks very much for following up.

Disabling the X Button and the File Exit is probably the way to go .

Again thanks for your patience with this.
0
 
LVL 17

Expert Comment

by:zzzzzooc
Comment Utility
Just to add to this...

You can add/remove the system menu-items via their IDs (system commands) such as SC_CLOSE for the "Close" item. To restore them, you can manually add the menu-item(s) back with the proper SC_* ID or just call GetSystemMenu() with bRevert as True to restore it.


Form1:
----------------
Option Explicit

Private Type MENUITEMINFO
    cbSize As Long
    fMask As Long
    fType As Long
    fState As Long
    wID As Long
    hSubMenu As Long
    hbmpChecked As Long
    hbmpUnchecked As Long
    dwItemData As Long
    dwTypeData As String
    cch As Long
End Type

Private Declare Function GetSystemMenu Lib "user32" (ByVal hWnd As Long, ByVal bRevert As Long) As Long
Private Declare Function InsertMenuItem Lib "user32" Alias "InsertMenuItemA" (ByVal hMenu As Long, ByVal un As Long, ByVal bool As Boolean, ByRef lpcMenuItemInfo As MENUITEMINFO) As Long
Private Declare Function DrawMenuBar Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function DeleteMenu Lib "user32" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long) As Long

Private Const MF_BYCOMMAND = &H0&
Private Const MFT_SEPARATOR = &H800
Private Const MFT_STRING = &H0
Private Const MIIM_STATE = &H1
Private Const MIIM_ID = &H2
Private Const MIIM_STRING = &H40
Private Const MIIM_FTYPE = &H100
Private Const SC_CLOSE = &HF060&
Private Sub Form_Load()
    '
End Sub
Private Sub Command1_Click()
    Dim hMenu As Long
    hMenu = GetSystemMenu(Me.hWnd, False)
    If (DeleteMenu(hMenu, SC_CLOSE, MF_BYCOMMAND) <> 0) Then
        Call DrawMenuBar(Me.hWnd)
        Call MsgBox("Menu deleted.")
    End If
End Sub
Private Sub Command2_Click()
    Call GetSystemMenu(Me.hWnd, True)
    Call DrawMenuBar(Me.hWnd)
   
    'Manually add the menu item...
    '
    'Dim hMenu As Long
    'Dim tMII As MENUITEMINFO
    'hMenu = GetSystemMenu(Me.hWnd, False)
    'With tMII
    '    .cbSize = Len(tMII)
    '    .dwTypeData = "Close" & vbNullChar
    '    .cch = Len(tMII.dwTypeData)
    '    .fMask = MIIM_STATE Or MIIM_ID Or MIIM_STRING Or MIIM_FTYPE
    '    .fType = MFT_STRING
    '    .wID = SC_CLOSE
    'End With
    'If (InsertMenuItem(hMenu, SC_CLOSE, MF_BYCOMMAND, tMII) <> 0) Then
    '    Call DrawMenuBar(Me.hWnd)
    '    Call MsgBox("Menu added.")
    'End If
End Sub
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

When designing a form there are several BorderStyles to choose from, all of which can be classified as either 'Fixed' or 'Sizable' and I'd guess that 'Fixed Single' or one of the other fixed types is the most popular choice. I assume it's the most p…
Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

728 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now