|
Thank you Markus for making Windows a better place! This software provides functionality Windows should have out of box. I like it very much. However, there were a couple of annoying features: I didn't understand the code and it didn't compile on MinGW.
I ported the code to MinGW and rewrote it in C (because I can't write C++ and could not get g++ to generate working binaries). I added a check to discard WM_RBUTTONUP when alt is down to prevent context menus from popping up. I stripped the tray icon (because I didn't feel like learning to to use windres). Because I stripped the tray icon I also wrote a killer app to tell the DLL host to exit.
I'd like to post the code in a new article here on CodeProject if it's OK with you, Markus. I'd also like to rename the software to WindowShifter to avoid confusion (or create it, you could mistake that for an Alt-Tab replacement for example). The string WindowShifter turns up very few matches on Google so it's pretty unique.
Perhaps in the future I'll look into implementing the last missing feature---scroll focus under cursor just like in most X11 window managers. Windows' scroll focus policy has always frustrated me and I think it's time to remedy that. I have a hook application that came with a mouse, LwbWheel.exe, that does just what I want but it's not open source.
|
|
|
|
|
Yes I'm happy with a fork and you're efforts to improve this little tool I'm looking forward to your improvements and I'm definitely going to try them...
|
|
|
|
|
Hey Foobarz, I still use Markus Rollman's excellent utility in 2021 on my aging XP system but I would be interested if you completed your forked version.
I know you wrote in 2008 and now I am writing over a decade later but did you post the code? I can't find anything.
If anyone knows where I can get your version then please let me know.
|
|
|
|
|
Cool! I really like it!
|
|
|
|
|
Just what I was looking for
|
|
|
|
|
Exactly! Recently I already found KatMouse (http://www.code-scout.net/katmouse/), which sends mousewheel events to the window(-element) under the mousepointer, instead of the active window.
And now my search for the handling i was missing in windows is complete!
|
|
|
|
|
|
Does anyone know how one could prevent users from resizing windows in general using hooks? I just want to be able to remove the "size" option in your file menu form as well as the resizing lines at the bottom right of the window.
|
|
|
|
|
any chance of making windows snap to one another and the edge of the screen?
similar to: http://www.cs.utoronto.ca/~iheckman/allsnap/
if so, i would use this app all the time!
thanks for the base program too!
mmanson132
|
|
|
|
|
I had this commercial utility called Virtual Environment (venv.exe). It's no longer available nor supported. It had similar functionality among other things. It had one advantage over WM. If for example a window has a modal dialog opened over it (example: open notepad and select file->open) it is not possible to move the window under the dialog with WM. Venv was able to do this. Do you think this
would be possible to implement to WM?
I also have a few utilities of my own. One of them pastes text with shift-<middle mouse="" button=""> click. Perhaps this would be useful in WM, too? After all, it's an X Windows like feature.
Here's roughly how to do it:
__________________________________________________________________
static HHOOK hhook;
static LRESULT CALLBACK MouseHook(int code, WPARAM wParam, LPARAM lParam)
{
int u = code;
MSLLHOOKSTRUCT* mouse = (MSLLHOOKSTRUCT*)lParam;
int btn = wParam;
if (btn == WM_MBUTTONDOWN)
{
if ((GetKeyState(VK_RSHIFT) & 0xf000) ||
(GetKeyState(VK_LSHIFT) & 0xf000))
{
Paste();
}
}
return CallNextHookEx(hhook, code, wParam, lParam);
}
void AttachMouse()
{
hhook =
SetWindowsHookEx(WH_MOUSE_LL,
MouseHook,
GetModuleHandle(NULL),
0);
}
void
Paste()
{
HWND haistite = ::GetForegroundWindow();
if (haistite)
{
POINT p;
GetCursorPos(&p);
CWnd* h = WindowFromPoint(p);
if (!h) return;
h->ScreenToClient(&p);
CWnd* haist = h->ChildWindowFromPoint(p, CWP_SKIPINVISIBLE | CWP_SKIPDISABLED);
if (!haist) haist = h;
// Position the cursor under mouse cursor.
haist->SendMessage(WM_LBUTTONDOWN, 0, MAKELONG(p.x, p.y));
haist->SendMessage(WM_LBUTTONUP, 0, MAKELONG(p.x, p.y));
// Paste.
// Simulate shift-insert. For reason or another,
// SendMessage -based approach does not work and neither
// could I SendInput() a ctrl-v. Also,
// haist->PostMessage(WM_PASTE, 0, 0);
// only works for CEdits and simple controls, not with MS Word or MSVC.
INPUT shift_insert[4];
memset(shift_insert, 0, sizeof(shift_insert));
shift_insert[0].type = INPUT_KEYBOARD;
shift_insert[0].ki.wVk = VK_SHIFT;
shift_insert[0].ki.dwFlags = KEYEVENTF_EXTENDEDKEY;
shift_insert[1].type = INPUT_KEYBOARD;
shift_insert[1].ki.wVk = VK_INSERT;
shift_insert[1].ki.dwFlags = KEYEVENTF_EXTENDEDKEY;
shift_insert[2].type = INPUT_KEYBOARD;
shift_insert[2].ki.wVk = VK_INSERT;
shift_insert[2].ki.dwFlags = KEYEVENTF_KEYUP | KEYEVENTF_EXTENDEDKEY;
shift_insert[3].type = INPUT_KEYBOARD;
shift_insert[3].ki.wVk = VK_SHIFT;
shift_insert[3].ki.dwFlags = KEYEVENTF_KEYUP | KEYEVENTF_EXTENDEDKEY;
SendInput(4, shift_insert, sizeof(shift_insert[0]));
return;
}
}
__________________________________________________________________
|
|
|
|
|
Anonymous wrote:
> I works great, thanks!
Thank you, I always welcome feedback
[...]
> (example: open notepad and select file->open) it is not possible to
> move the window under the dialog with WM.
You're right- I just tried it. I didnt' notice it before.
[...]
> Venv was able to do this. Do you think this would be possible to
> implement to WM? (Unfortunately, I don't have the source code for
> venv.exe).
Mmmh... i don't know exactly what causes this behavior. WM should be
able to find the window underlying the modal dialog just like any
other with the WindowFromPoint() function.
The SetWindowPos() function I'm using just fails to move a window
below a modal dialog. Maybe some special flags allows it to do
so... I'll have to experiment a bit more.
> I also have a few utilities of my own. One of them pastes text with
> shift-<middle mouse="" button=""> click. Perhaps this would be useful in
> WM, too? After all, it's an X Windows like feature.
Yes, it seems like a good idea. I'll have a look into it.
regards,
Markus
|
|
|
|
|
I was waiting after a small tool like this, which will also work with WinRoll which I like a lot... And this is the case.
I didn't experienced any trouble with my virtual desktop setting so it's also great!
Could you change the shape of the mouse, accordingly with the underlying action?
Thanks a lot!
regards,
Eric
|
|
|
|
|
Well I love this program and would find it hard to live without it now, so I've started to get around to fixing someof the annoying things in it =)
To stop moving of maximised windows in wmmousedll.cpp just before the code
<br />
switch (opMode) {<br />
case O_MOVE :<br />
put this
WINDOWPLACEMENT wndpl;<br />
::GetWindowPlacement(hWnd, &wndpl);<br />
if(wndpl.showCmd == SW_MAXIMIZE)<br />
return CallNextHookEx(hhook, nCode, wParam, lParam);
Another addition is just after the code I added above is this piece of code
char dada[20];<br />
GetClassName(hWnd,dada,20); <br />
if(stricmp(dada, "TSSHELLWND") == 0) return CallNextHookEx(hhook, nCode, wParam, lParam);
You can replace TSSHELLWND with the class of any window you dont want to be able to drag around like this, in this case (TSSHELLWND) is remote desktop. This could be extended to have a UI letting you add more window classes (or even better exe names and paths, but I dunno how to do that)
This program stops Alt-Clicks getting through to the window at all, this is not desirable but would be hard to fix nicely.
One way is in the cases
case WM_RBUTTONDOWN :
case WM_LBUTTONDOWN :
You really count return 0; instead of 1.
Admittedly this has other problems, as sometimes I want to resize instead of alt-clicking a button and with my change it will perform both. I'm guessing a fix for this would be to send a mouse click to the window on mouse up if the mouse did not move instead of the return 0 fix.
-- modified at 20:00 Wednesday 7th September, 2005
|
|
|
|
|
Twink wrote:
Well I love this program and would find it hard to live without it now, so I've started to get around to fixing someof the annoying things in it =)
Thank you, I'm also still using this little tool...
I added your fix regarding the handling of maximised windows and submited a new version to CP.
Your second suggestion regarding filtering of remote desktop desktop windows is to specific I think for the public CP version. However I like the idea implement some filtering based on window state or windw classes.
Therefore I created a dedicated function 'FilterWindow', where new filter can be implemented without cluttering the existing code. Your test for maximised windows is the first filter there.
The problem with customizing the tool is not to write a gui or read an ini file but to allocate and share the config data between the different dll instances. The current approach is a static fixed sized data section visible to all instances.
I think the proper way could be to stuff a HGLOBAL handle into this section and move any variable sized config data into a section allocated with GlobalAlloc?
Markus
|
|
|
|
|
You're definetely correct about the major problem being the sharing of the data, I tried several times and failed due to this. There's an article over at CodeGuru that uses memory mapped files to share data (http://www.codeguru.com/Cpp/misc/misc/ipctechniques/article.php/c305/) however GlobalAlloc sounds like it might work too.
MSDN has a section on it too: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore/html/_core_How_do_I_share_data_in_my_DLL_with_an_application_or_with_other_DLLs.3f.asp
|
|
|
|
|
wmmousedll.cpp
LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam )
//this is error.
MOUSEHOOKSTRUCT &mhs = *(MOUSEHOOKSTRUCT*)wParam;
//this is fix bug.
MOUSEHOOKSTRUCT &mhs = *(MOUSEHOOKSTRUCT*)lParam;
|
|
|
|
|
yes and no
Yes, it's an error, as lparam contains the pointer to the MOUSEHOOKSTRUCT. And no it's not, as 'mhs' is never used below the mentioned line. You may count it as the second error though I'll fix it along with the the next serious bug, that will surely be spotted.
|
|
|
|
|
This is really great! Thank you for sharing it!
I really do not understand the relatively low average rating... Maybe too many of us rely on pictures...
However, here is my 5!
|
|
|
|
|
I really hope you could include a figure inside the article, which will definitely poooop the popularity (some lazy guys, especially). The program, I have to say, is very creative itself. Good!
|
|
|
|
|
I just updated the source to fix a bug, pointed out by Whosit.
When the alt key ist relased while dragging or sizing a window the mouse capture is now released correctly.
|
|
|
|
|
Cool! Tested it out and it additionally fixed that bug of where it would still move/resize on the second mouse-click even w/o the alt key. Great
Just had to add back in my VK_SHIFT check, but thats mine anyways, so...
Great Work!
|
|
|
|
|
When i alt+mouse, it works fine. But.. the next time i use the mouse, even withOUT the alt, it still works as though the alt were on. But then the next time if the alt key is still up, then it works as it ought.
It seems to hold on to the capture too long or something, but i cant seem to figure out how to turn it off.
??
|
|
|
|
|
Yes, you're right! There seems to be a bug
Once you press alt+mouse you can start dragging the window. The problem is that from this point onward, the status of alt isn't checked anymore, so you can release the key and still drag the window until you also release the mouse button.
I'll see if I can fix it.
|
|
|
|
|
Well, i dont know how the UNIX ones work of that you talk about, but i kind of like that you can release the ALT key and it still goes as long as you hold the mouse button down.
I just think you when you release the mouse button it should then release its capture.
Im confused though, because it looks like it should do that in the default case for the top-level switch in the MouseProc, i just cant see why it doesnt.
|
|
|
|
|
In the unix world you can only drag the window as long as you press the alt key.
I think I now understand what you mean. It is indeed possible to drag the window without pressing alt after the release of both alt key and mouse button.
I tried putting a call to ReleaseCapture(); in the default cas e as you suggested but it doesn't fix it. I think I'll have to take a deeper look.
But thanks for the bugreport
|
|
|
|