.NET Forum / .NET Framework / Interop / April 2004
Disable x button of another program
|
|
Thread rating:  |
Gerry Viator - 22 Apr 2004 17:31 GMT Hi all,
I want to disable the x button of an old dos based program?
I guess I will need a process running in the background ?
thanks for any help
Gerry
"Ying-Shen Yu[MSFT]" - 23 Apr 2004 05:10 GMT Hi Gerry,
I'm not clear which "X" button do you refer to. do you mean the close button of the Command Prompt window? or it's a button in your dos program?
Best regards,
Ying-Shen Yu [MSFT] Microsoft Community Support Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties and confers no rights. This mail should not be replied directly, please remove the word "online" before sending mail.
Gerry Viator - 23 Apr 2004 15:03 GMT yes,
The close button the command window.
I need to some how disable that X button(Close button) in a old DOS base application. The cmd window of that application.
Is there a windows message that I can intercept based on that process running and then tell the user to hit excape key to Exit or send key method of the esc key the application.?
MORE INFORMATION Oh, I did not mention that the user should be hitting the esc key to Exit the application and not the close button of the cmd window of that DOS base application.. The problem is a locking issue on the Server side but no need to go there. I need to change it on the client side.
Also is it possiable to get the cordinates of the cmd window, I was thinking that I could put a new Close X button(form) in front of that one, no matter where that cmd window was moved , the dummy one would be in front. of the DOS one.
Matbe my application could use a timer to check all the time for that process that is opened then I could put a small none active Close button in front of the other one?
Thanks again for your help
Gerry
> Hi Gerry, > [quoted text clipped - 11 lines] > This mail should not be replied directly, please remove the word "online" > before sending mail. "Ying-Shen Yu[MSFT]" - 26 Apr 2004 08:48 GMT Hi Gerry,
For disabling the the "X" button as well as the "Close" mentu item in the system menu, we can find the corresponding window and delete the SC_CLOSE menu item. Here is a demo snippet in C++, it just find a window whose window class is "ConsoleWindowClass" (the window class name of CommandPrompt) then modify the close menu button. After running this prorgram, the X button of the command prompt will gray out, and the Close menu item will disappear. <code> int _tmain(int argc, _TCHAR* argv[]) { HWND hWnd = ::FindWindow("ConsoleWindowClass",NULL);//Find window
HMENU hMenu = GetSystemMenu(hWnd,FALSE); DeleteMenu(hMenu,SC_CLOSE,MF_BYCOMMAND); RECT rc; ::GetWindowRect(hWnd,&rc); SetWindowPos(hWnd,HWND_NOTOPMOST,rc.left,rc.top,rc.right - rc.left,rc.bottom - rc.top,SWP_FRAMECHANGED); printf("put any key to continue"); getchar(); return 0; } </code>
For more complex behavior (e.g. overriding the behavior of the close button etc.) it requires more advanced techniques since we are modifying the Command Prompt from a seperate process, to respond to the event happened in another process we need to use hook or inject code the command prompt process. It's a bit invasive and may hurt the stability of your dos program(since it's running in the dos box). If you would like to try it, you may first read the documentation of Win32 hooks for more information, also I suggest you implement it in C/C++, since they are more suitable for this scenario.
<Win32 Hooks> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwui/html/ msdn_hooks32.asp
Thanks!
Best regards,
Ying-Shen Yu [MSFT] Microsoft Community Support Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties and confers no rights. This mail should not be replied directly, please remove the word "online" before sending mail.
Gerry Viator - 26 Apr 2004 13:40 GMT Thanks for your help,
Can you or someone translate this to VB.NET
thanks Gerry
> Hi Gerry, > [quoted text clipped - 34 lines] > > <Win32 Hooks> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwui/html/
> msdn_hooks32.asp > [quoted text clipped - 9 lines] > This mail should not be replied directly, please remove the word "online" > before sending mail. "Ying-Shen Yu[MSFT]" - 27 Apr 2004 03:51 GMT Sure, Here is the VB.NET version, create a winform app project to test it. It's just a rough sample to show you how to do it in VB.NET, I didn't do many tests on it, so there might be some errors, if you have problem to run the test code, please let me know.
Thanks!
<code> Private Sub button1_Click(ByVal sender As Object, ByVal e As EventArgs) Begin Sub Dim ptr1 As IntPtr Dim ptr2 As IntPtr Dim rect1 As Rect
'Use your own way to find the console window ptr1 = Form1.FindWindow("ConsoleWindowClass", Nothing) ptr2 = Form1.GetSystemMenu(ptr1, 0) 'DeleteMenu(hMenu,SC_CLOSE,MF_BYCOMMAND); Form1.DeleteMenu(ptr2, 61536, 0) Form1.GetWindowRect(ptr1, AddressOf rect1) 'SetWindowPos(hWnd,HWND_NOTOPMOST,rc.left,rc.top,rc.right - rc.left,rc.bottom - rc.top,SWP_FRAMECHANGED); Form1.SetWindowPos(ptr1, -2, rect1.left, rect1.top, (rect1.right - rect1.left), (rect1.bottom - rect1.top), 32) End Sub
<DllImport> Private Shared Function DeleteMenu(ByVal hMenu As IntPtr, ByVal pos As Integer, ByVal flags As Integer) As IntPtr
<DllImport> Private Shared Function FindWindow(ByVal clsName As String, ByVal wndName As String) As IntPtr
<DllImport> Private Shared Function GetSystemMenu(ByVal hwnd As IntPtr, ByVal force As Boolean) As IntPtr
<DllImport> Private Shared Function GetWindowRect(ByVal hwnd As IntPtr, [out] ByRef rc As Rect) As Integer
<DllImport> Private Shared Function SetWindowPos(ByVal hwnd As IntPtr, ByVal window As Integer, ByVal x As Integer, ByVal y As Integer, ByVal cx As Integer, ByVal cy As Integer, ByVal flag As Integer) As Integer
Private Structure Rect Public bottom As Integer Public left As Integer Public right As Integer Public top As Integer End Struct
Best regards,
Ying-Shen Yu [MSFT] Microsoft Community Support Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties and confers no rights. This mail should not be replied directly, please remove the word "online" before sending mail.
Gerry Viator - 27 Apr 2004 15:56 GMT Hello,
Ok thanks for your help.
This is what I have (see below), seems to work but a little slow? I would like to check in the tick event to only disable it if it is not disabled? Is this way ok, better way to do this?
What would be great if this is only run once every time the "Dos application is opened"?
Thanks for your help
Module Module1
Private Declare Function DeleteMenu Lib "user32" (ByVal hMenu As Integer, ByVal uPosition As Integer, ByVal uFlags As Integer) As Boolean
Private Declare Function DrawMenuBar Lib "user32" (ByVal hwnd As Integer) As Integer
Private Declare Function GetMenuItemCount Lib "user32" (ByVal hMenu As Integer) As Integer
Private Declare Function RemoveMenu Lib "user32" (ByVal hMenu As Integer, ByVal nPosition As Integer, ByVal wFlags As Integer) As Integer
Private Declare Auto Function FindWindow Lib "user32" (ByVal lpClassName As String, _
ByVal lpWindowName As String) As Integer
Private Declare Function GetSystemMenu Lib "user32" (ByVal hWnd As Integer, ByVal bRevert As Boolean) As Integer
Private Const lpClassName = "Command Prompt"
Private Const MF_DISABLED = &H2&
Private Const MF_BYPOSITION = &H400&
Private WithEvents XTimer As New System.Windows.Forms.Timer
Sub Main()
XTimer.Interval = 2000
XTimer.Enabled = True
XTimer.Start()
Application.Run()
End Sub
Private Sub XTimer_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles XTimer.Tick
DisableX()
End Sub
Private Function DisableX()
Dim hwnd As Integer = FindWindow(vbNullString, lpClassName)
Dim hMenu As Integer = GetSystemMenu(hwnd, False)
'DeleteMenu(hMenu, 6, 1024)
Dim nCount As Integer
'Get number of items in menu
nCount = GetMenuItemCount(hMenu)
'Remove last item from system menu (last item is 'Close')
'Call RemoveMenu(hMenu, nCount - 1, MF_DISABLED Or MF_BYPOSITION)
DeleteMenu(hMenu, 6, 1024)
End Function
End Module
> Sure, Here is the VB.NET version, create a winform app project to test it. > It's just a rough sample to show you how to do it in VB.NET, I didn't do [quoted text clipped - 59 lines] > This mail should not be replied directly, please remove the word "online" > before sending mail. "Ying-Shen Yu[MSFT]" - 28 Apr 2004 03:26 GMT Hi Gerry,
Then, can we use a bat file to wrapper the command to start your application?
To disable the close button in a bat file, you may first create a VB.NET console project, use the previous code to disable the close button of current console window ( you can get HWND using GetConsoleWindow API on XP or later, for win98/2000 you may still need to enumerate the window using FindWindow). Note you may need add the SetWindowPos call with SWP_FRAMECHANGED after deleting menu, since several window state are cached so the window apprearance may not reflect the change immediately, as doc states SWP_FRAMECHANGED will force update these window state.
Finally write a bat file, put the vb.net console program before the real program start command, give the shortcut to the bat file to the end-user.
Does this way resolve your problem?
Best regards,
Ying-Shen Yu [MSFT] Microsoft Community Support Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties and confers no rights. This mail should not be replied directly, please remove the word "online" before sending mail.
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|