How does WinTabber work? - winapi

How does WinTabber work? It can take the main window of another application and display it as a WinTabber child window. What system calls do this?

You have to use SetParent(). And probably MoveWindow() to force the app to fit its main window in your tab. And you'll have to do something reasonable when the process opens other toplevel windows, a WH_SHELL hook is probably needed. And probably a bunch of hacks to whack popular programs into shape that don't like you messing with their main window.

Related

Win32 C++ - Do something when window is restored, which message?

So, I have a dialog based application using pure WinAPI. There is a main dialog, and then multiple other dialogs that are toolwindows. These toolwindows are meant to free-float around, the user can drag them, hide them, and show them, but they have no taskbar entry. This is what I intended, but the problem is, when I switch from the main window to a different application, then click on the taskbar entry for the main window, the main window will show up, but the toolwindows will not. They stay hidden behind the main window and sometimes windows of other applications, and you cannot use them until you move all of the top-most windows and hunt down the toolwindow.
So, what I'm trying to do to work around this is, when the user restores the window from being minimized, I want to enumerate through all of the tool windows and bring them to the front, maybe by calling SetActiveWindow().
But what message gets sent when the window is restored? I was thinking WM_SHOW, or WM_RESTORE, but they don't exist.
Another question, and if you answer this the first question is irrelevant because I will no longer need to use that workaround: Is there a better method of bringing all tool-windows to the front?
Give the tool windows the WS_POPUP style (and not WS_OVERLAPPED), and make the main window their parent (strictly it is their owner window). That way the tool windows will remain on top of the main window. This may (or may not) be what you want.
The naive answer to the question is to listen to WM_SIZE and respond to a wParam value of SIZE_RESTORED.
The other obvious possibility is to make all the tool windows be owned by the main window. So long as you are happy for the tool windows always to be on top of the main window, this will solve your problem. The owned windows will be hidden when the owner is minimized, and re-shown when the owner is restored.
Learn more about ownership in the MSDN topic on Window Features.

Show a popup menu in another application's window

How can a Delphi XE application show a popup menu inside another application's window? The idea is for a helper-type app, running in the background. On a registered hotkey the application needs to display a popup menu near the text caret or mouse cursor.
Applications that do that are common, here's a menu created by AutoHotkey and displayed in a text editor:
I guess what I'm asking is: how can I display a popup menu at an arbitrary screen location, without it being attached to a Delphi control?
Create a TPopupMenu with the appropriate menu items. When you need to show it simply call Popup passing the top left position in screen coordinates.
PopupMenu1.Popup(X, Y);
#DavidHeffernan answered your question, but you might not have asked the right question.
Let's take the example you gave: the user is running some arbirary application, and you want to be able to detect a hotkey, display a menu, and then take some action based on the menu item chosen (and maybe even the user's context, such as the word under the cursor). This is more complicated than simply displaying a menu at arbitrary screen coordinates.
My recommendation is to use AutoHotKey instead of trying to replicate this in some other programming language. In case you're not aware of this, it is possible for your code to run AutoHotKey scripts. IIRC, you can compile AHK scripts, so you wouldn't need to install AHK, just the compiled scripts. AHK may not be the most elegant of solutions, but it has depth and maturity.
If this is not possible, then I suggest you research Windows Hooks and DLL Injection. Unless you can find some preexisting code or framework, this will entail quite a bit of work.
The reason for this complexity? To augment another program smoothly (without running into problems with focus, etc.) you want to have your code run as part of that other program. The mechanics of this can be done via DLL injection. However, that's only the first step. Once your code is running in the right context, then your code has to inter-operate with the "host" program. This can be tricky (it helps if you have deep experience with Windows messaging and the Windows API). If you want this to work smoothly with any arbitrary program, it gets even harder.

Create a background process in windows

How do I make a process go the background programatically?
What I want is for the user to double-click the process executable, and it just goes into the background ... and does not open a window while executing.
Any code snippet in visual c++ would be very helpful
Have you considered creating a Windows Service instead? They're specifically designed to run in the background without showing a UI.
Otherwise, just create an application without a window.
I know this is old, but I thought I would post something for when people find this through search.
While I like Cody Gray's answer for design correctness, sometimes you don't have a choice.
If you want to launch a program without jumping to the new window (it appears in the background or minimized) or not create a window at all try looking at the ShellExecute and ShellExecuteEx functions. The argument nShowCmd (or nShow) gives you (among others) the options:
SW_HIDE
Hides the window and activates another window.
SW_SHOWMINNOACTIVE
Displays the window as a minimized window. The active window remains active.
As the documentation says, SW_HIDE creates a process running the executable you give it, but if this program would normally create a window, none appears.
This might help: http://ss64.com/nt/start.html
I tried this way and it worked fine:
Create a console application and write your codes in the sub main as any other console application.
Now change the application type in the project properties to windows Forms application from Console application
thats it

Create a Program that Sits in The Windows Taskbar and, When Activated, Stops the Screensaver From Starting

I don't really know where to begin. Let's start with the stupid questions:
What language should I use for this? What is suited for the task at hand?
Next, the real ones:
Is there a way to stop the screensaver from starting, short of changing the cursor position? If not, will changing the cursor position even work?
SetThreadExecutionState will prevent the screensaver from coming on or the machine from automatically going to sleep if you pass the ES_CONTINUOUS and ES_DISPLAY_REQUIRED flags.
I wrote an app awhile ago that does exactly what you are asking for. It runs as an icon in the System Tray, not the Taskbar, and uses a global message hook to disable the WM_SYSCOMMAND/SC_SCREENSAVE notification from reaching any applications. If that notification does not reach the DefWindowProc() function, the screen saver will never run.
Your program does not need to be visible in the task bar at all.
You don't even need a program at all, if you can disable the screensaver in the registry.
What you want to do can perhaps be achieved by sending a MOUSE_MOVE event to the desktop window. If you want to use C# (the only language I am current with right now), you can look at this article, but maybe a simple C program using the WinAPI is better suited for this task.
.NET will easily allow you to put an application in the system tray (checkout the NotifyIcon object in System.Windows.Forms.Controls).
I believe you can use the SetCursorPos (http://msdn.microsoft.com/en-us/library/ms648394(VS.85).aspx) API call to prevent the screen saver, just make sure you set them to the current location so you don't actually move the mouse.

How can I post a Cocoa "sheet" on another program's window?

Using the Apple OS X Cocoa framework, how can I post a sheet (slide-down modal dialog) on the window of another process?
Edit: Clarified a bit:
My application is a Finder extension to do Subversion version control (http://scplugin.tigris.org/). Part of my application is a plug-in (a Contextual Menu Item for Finder); the bulk of my application, however, is in a separate daemon proces. For several reasons, we've chosen to put virtually all the code into the daemon; the plug-in only defines the menu itself, and Apple-Events over to the Daemon.
Sometimes, the daemon needs to prompt the user for further information. It can toss a window on-screen for this, but that's disruptive (randomly positioned), and it seems to me the work flow here is legitimately modal, for example "select a file, pick 'commit' from the menu, provide commit comments, do the operation."
Interprocess cooperation (such as passing a reference of some kind) is acceptable: both processes are mine, but I want to avoid binding the sheet's code into the primary process.
Really, it sounds like you're trying to have your inter-process communication happen at the view level, which isn't really how Cocoa generally works. Things will be much easier if you separate your layers a bit more than that.
Why don't you want to put the sheet code into the other process? It's view code, and view code is inherently process-specific. The right thing to do here is probably to add somewhat generic modal-sheet support to your plugin code, and an IPC call that your daemon can make to summon that code. Trying to ship view objects over to the remote process is going to be nightmarish if you can make it work at all.
You're fighting the frameworks with this approach.
You can't add a sheet to a window in another process, because you have at most only the most restricted access to the windows in the other process.
Please don't do this. Make the interaction nonmodal if at all possible. Especially in something like a commit, it's much nicer to be able to browse around your files while you're writing commit comments.
OS X does have window groups, but I don't think they can (easily) span applications.
Another thing to consider is that in OS X it's possible to have many Finder windows open on the same folder (unlike in OS 9). Even if you did have sufficient privileges/APIs to add a sheet to a Finder window, it's not like the modality of that window would prevent the user from being able to continue working with the files.
(My personal opinion as a long-time Mac user is that this kind of interaction would drive me right up the wall.)

Resources