MFC message pump vs Win32 message loop - winapi

Well, I am bit confused. Things looked nice when I studied message loop in Windows programming from Programming Windows (Charles Petzold). I completed initial 3 chapters (Windows messages, message loops and stuff) and thought to plunge into MFC, so now has taken up Programming Windows with MFC (Jeff Prosise).
Now the question is Is message pump in MFC is same as message loop in Win32 programming? Or is it different concept? If different, what does that mean?
Thanks in advance!

They're roughly the same thing.
MFC's message pump implements a message loop, but introduces the PreTranslateMessage() method into the mix so dialog messages can be translated by their own class instead of the main loop.
See Meandering Through the Maze of MFC Message and Command Routing for additional details about this feature.

Related

What is Subclassing and API Hooking?

I am fairly new to Windows API Programming and I want to know in layman's terms what is subclassing and API Hooking. I am doing a project that uses owner drawn controls, and I two terms keep coming up. Now I have already seen a lot of detailed tutorials on CodeProject.com about these topics, but the problem is that all of them use MFC, and I am coding in pure Win32. If anyone knows about any good tutorials of the above mentioned topics then please post the links. Also try to avoid links to the msdn, as novice I am having trouble making sense of whats written there.
Layman terms: sub-classing is done by replacing the window procedure of a window. Which redirects the calls that Windows makes to deliver a message to a window to your function so you get to see those messages first. This lets you change the behavior of the window, giving it new capabilities that the original one didn't have. It is a very common technique and directly supported by the OS, the SDK article is here.
API hooking is similar but for winapi functions. So that you can change the behavior of code that runs in your process that you didn't write. Arbitrarily, you could hook CreateFile() and change the passed file name or make it fail on purpose. It is much less common to do this and also much harder to get right since it is not a baked-in capability like sub-classing is. Microsoft's Detours is an example implementation of the technique.
Either technique is in the advanced programming category and you can get yourself into pretty nasty trouble if you don't do it right. If you have trouble reading the MSDN articles right now then leave it on the shelf until you're ready for it.
If you are programming raw Win32 you should probably get the Petzold book "Programming Windows".

Visual Basic 6 - Any libraries exist to allow implementation of multithreading?

Are there any libraries that I can import into a VB6 project to enable multi threaded support? I know that there are examples using the Windows API but I was wondering if there are any libraries that already exist that I can just import into my project to allow this functionality in VB6. I have inherited a very complex application in VB6 that one of its tasks is to control a multi-million dollar robotic arm. I need to take this application and make some changes that would benefit greatly if I can add multithreaded support. Converting this application to .NET would be an enormous undertaking (to us a good analogy would be the equivalent of a manned mission to Mars next year). The application includes several custom libraries that perform complex scientific calculations and data analysis. The code has been customized to deliver an impressive processing speed (this is VB6). It would take an enormous amount of resources to migrate to a .NET platform. Executive management indicates it could easily be 8 years before the system is upgraded. I would appreciate any responses.
Note: I did a search before submitting this question and I did see a similar question being asked but the answer to the question directs to the Windows API directly. My question is a bit different. I am asking about libraries that already include this functionality that I can use in this project. That is, libraries that have already done all this work of using the API.
There's no library for multithreading that I know of. But asynchronous processing does not necessarily require threads. Desaware have StateCoder, a library for state machines which helps with multi-tasking without multi-threading. A bit like the Aysnc CTP.
Alternatively here is a pretty standard scheme for asynchronous background processing in VB6. (For instance it's in Dan Appleman's book and Microsoft's VB6 samples.) You create a separate ActiveX EXE to do the work: that way the work is automatically on another thread, in a separate process (which means you don't have to worry about variables being trampled).
The VB6 ActiveX EXE object should expose an event CheckQuitDoStuff(). This takes a ByRef Boolean called Quit.
The client calls StartDoStuff in the ActiveX EXE object. This routine starts a Timer on a hidden form and immediately returns. This unblocks the calling thread. The Timer interval is very short so the Timer event fires quickly.
The Timer event handler disables the Timer, and then calls back into the ActiveX object DoStuff method. This begins the lengthy processing.
Periodically the DoStuff method raises the CheckQuitDoStuff event. The client's event handler checks the special flag and sets Quit True if it's necessary to abort. Then DoStuff aborts the calculation and returns early if Quit is True.
This scheme means that the client doesn't actually need to be multi-threaded, since the calling thread doesn't block while "DoStuff" is happening. The tricky part is making sure that DoStuff raises the events at appropriate intervals - too long, and you can't quit when you want to: too short, and you are slowing down DoStuff unecessarily. Also, when DoStuff exits, it must unload the hidden form.
If DoStuff does actually manage to get all the stuff done before being aborted, you can raise a different event to tell the client that the job is finished.
Disclaimer: direct copy of my answer on another question
You can certainly call the windows API to implement multi threading, and its not actually that complicated. However, the simplest solution would be to expose a .net Com object and implement multi threading through .net. For complicated already existing functionality you can break the vb6 app into com libraries that can be called by by the multi threaded .net controller.
[Gui] ┬> [ .net Com Mulit thread controller] -> [Com exposed VB 6 utility]
|
└> [Com exposed VB 6 utility]
See the article Using Background Threads with Visual Basic 6 for an elegant answer to the problem.
There was a threading library made by elitevb in 2002 which is unfortunately closed now.
But there is an archive of elitevb articles on xtremevbtalk.
In the section System and devices there is a post at the bottom with the threading.dll and sample source code attached, which makes it very easy to implement threading. As far as I remember, there was the problem, that testing it in the IDE crashed the program, but there were no problems running the compiled program.
With the library, you could create threads pretty straitforward:
Dim ReadValuesThread As Thread
Private Sub Form_Load()
Set ReadValuesThread = New Thread
ReadValuesThread.StartThread "ReadValues", "None", Me
' Public Function StartThread(FunctionName As String, _
' FunctionParameter As Variant, _
' ParentObject As Object) As Long
End Sub
Private Sub ReadValues()
' do things
End Sub
Private Sub Form_Unload(Cancel As Integer)
' kill thread
ReadValuesThread.EndThread
End Sub

How to close a shelled process in VB6

I shell out an application from my VB6 app. I would then like to close it. How can I pull this off?
Here is Karl Peterson's VB6 method for closing applications. As you request, this asks nicely - sending WM_CLOSE rather than using TerminateProcess. Note that it sends the message to all of the top-level windows belonging to the process, there could be more than one.
I haven't tried this, but in my experience Karl Peterson's code always rates five stars out of a possible five!
EDIT: Please note this is an edited version of the original answer, and now links to the latest version of Karl's code. If anyone has questions about this, Karl is still active on the VB6 newsgroup but I don't think he hangs out on Stack Overflow.
Check this out:
End an Application that was Started by the Shell Function

Win32 API For Shutting Down Another Process Elegantly?

I'm looking for a way to shutdown a windows app from another. Is there a way to do this?
Ideally I'd like something that basically mimics an ALT-F4, or pressing the 'X' in the top right corner or some such.
Alternatively, is there an application out there that does this already? tskill is a bit too harsh for what I have in mind.
EDIT: I did a little digging and found a MSDN Article with the Microsoft recommended approach.
Since this is a windows app you can send the WM_CLOSE message to the main window however keep in mind that if the application overrides handling of the WM_CLOSE message you may get unexpected results. Also keep in mind that use of win32 functions like TerminateProcess and ExitProcess can also have unpleasant side-effects (see the remarks sections on msdn) including global data in dll's getting compromised as well as deadlocks.
If you are responsible for having coded the target application I would recommend adding some form of built in termination mechanism that can be triggered externally (e.g. magic packet on the loopback address or pipes) that way you can be sure your application has cleaned up after itself appropriately.
According to your description this sounds like a windowed app. In that case you can send it a WM_CLOSE message to mimic the behavior when pressing the "X" button.
Another alternative is to use TerminateProcess, but this is probably what tskill does as well.
More powerful command to close app is:
PostMessage (myhnd,WM_ENDSESSION,TRUE,ENDSESSION_LOGOFF);
I'll first refer you to my answer to another question; although it was about Delphi and services, the answer is neither Delphi- nor service-specific. In short, there is no generic way to gracefully stop a program. The accepted answer for that question demonstrates posting a wm_Close message to a program's window.

Windows Systems Programming: Can a keystroke be sent to an open application that is not the currently active one?

I'm a bit rusty on my Windows system programming...
Is it possible for a program to send a keystroke (I'm guessing by SendMessage() api call) to another application, if the (open) target application does not currently have the focus? If it is possible, does it then make the target application become the active application, or does it still remain in the background?
Thanks in advance for any info you may be able to provide!
No, It will not change the focus, unless subsequent calls do setfocus. It will remain the same window order
PostMessage(hwndOther, WM_KEYDOWN, VK_ENTER, 0);
This works for me, but only under Windows XP.
But On Vista and Windows 7 I've too got problem. Propably with UIPI.
I am trying to send a message to process from a DLL injected to this process.
How to fix it?
From memory: Yes, No.
You are looking for WM_KEYDOWN:
PostMessage(hwndOther, WM_KEYDOWN, VK_ENTER, 0);
For a directed send of keystrokes, SendInput is the native method of choice, though it is subject to UIPI (integrity level) checks on Vista/2008/W7. You can't send keystrokes to an app that has an IL > yours.
A more general solution for capturing and redirecting input is a global keyboard hook (See the help for SetWindowsHookEx). But this is fairly hairy stuff - you have to cope with how you send the keystrokes on, you affect every process in the system because your code is effectively inserted in the input stream, it involves writing a native DLL... you have to know exactly what you're doing.
We use a global keyboard hook in our system (I wrote it), but we're a special case - a single function emergency call handling system. I wouldn't advise a global hook as a solution in general purpose Windows computing.
You don't need SendInput() or hooks
The answer with PostMessage is wrong.
You must attach remotely your thread. See on Win32 api Group where it's a very classic question (C code, right MS method)
Yes you can send keystrokes, no it won't bring the other window to the top.
One way is to use the SendInput API function - here's an example of how to use it in VB6 (ulp!).
Probably easier to use GUI Automation which is supported directly from .NET Framework 3.0 - for instance read this.

Resources