News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Talking to the desktop

Started by Jimg, April 11, 2008, 05:34:27 PM

Previous topic - Next topic

Jimg

   I have a program that I wrote to put my desktop icons back where I want them when they get moved by some other process or situation beyond my control.
   
   The problem is that even though I can easily move the icons with code, turning off autoarrange and aligntogrid if needed, they will not hold.  In some situations, the desktop returns them to where they were before I moved them unless I manually click on at least one icon and move it somewhere after running my program.  This seems to lock in all the positions I set with my program.
   
   I have spent many hours trying to find some way to lock the positions in with code but have been unsuccessful.  So I've finally given up and am using the following code to emulate manually moving an icon-

    inv SetCursorPos,txpos,typos
    inv mouse_event,MOUSEEVENTF_LEFTDOWN,txpos,typos,0,0
    add txpos,10
    inv mouse_event,MOUSEEVENTF_MOVE,10,0,0,0
    inv Sleep,500
    inv mouse_event,MOUSEEVENTF_LEFTUP,0,0,0,0
    inv Sleep,500
    inv SetCursorPos,oldpos.x,oldpos.y
   
    Which works unless some other window is covering up the icon I'm trying to move, in which case the mouse movements go to that window instead.
   
    So, the only possibilities I can see are
   
    1. minimize all the windows on the desktop to be sure they are out of the way, or
   
    2. send the messages directly to the desktop.
   
    I've tried number two with no luck so far.  I trapped the messages to the desktop listview resulting from the above code with spy++ and, filtering out all the crud, they turn out to be-
   
0002008A P WM_MOUSEMOVE fwKeys:0000 xPos:15 yPos:170
0002008A S WM_SETCURSOR hwnd:0002008A nHittest:HTCLIENT wMouseMsg:WM_MOUSEMOVE
0002008A R WM_SETCURSOR fHaltProcessing:False
0002008A P WM_MOUSEMOVE fwKeys:0000 xPos:15 yPos:170
0002008A S WM_MOUSEACTIVATE hwndTopLevel:00020090 nHittest:HTCLIENT uMsg:WM_LBUTTONDOWN
0002008A R WM_MOUSEACTIVATE fuActivate:MA_NOACTIVATE
0002008A S WM_SETCURSOR hwnd:0002008A nHittest:HTCLIENT wMouseMsg:WM_LBUTTONDOWN
0002008A R WM_SETCURSOR fHaltProcessing:False
0002008A P WM_LBUTTONDOWN fwKeys:MK_LBUTTON xPos:15 yPos:170
0002008A P WM_MOUSEMOVE fwKeys:MK_LBUTTON xPos:23 yPos:170
0002008A S WM_SETCURSOR hwnd:0002008A nHittest:HTCLIENT wMouseMsg:WM_MOUSEMOVE
0002008A R WM_SETCURSOR fHaltProcessing:False
0002008A P WM_MOUSEMOVE fwKeys:0000 xPos:23 yPos:170
0002008A S WM_SETCURSOR hwnd:0002008A nHittest:HTCLIENT wMouseMsg:WM_MOUSEMOVE
0002008A R WM_SETCURSOR fHaltProcessing:False
0002008A P WM_MOUSEMOVE fwKeys:0000 xPos:23 yPos:170


I've tried to sendmessage directly to the listview like this:

    mov eax,typos
    shl eax,16
    or eax,txpos
    mov tmp,eax
    inv SendMessage,hListView,WM_MOUSEMOVE,0,tmp
    inv Sleep,100
    inv SendMessage,hListView,WM_LBUTTONDOWN,MK_LBUTTON,tmp
    inv Sleep,500
    mov eax,txpos
    add eax,10
    mov edx,typos
    shl edx,16
    or eax,edx
    mov tmp2,eax
    inv SendMessage,hListView,WM_MOUSEMOVE,MK_LBUTTON,tmp2
    inv Sleep,500
    inv SendMessage,hListView,WM_LBUTTONUP,0,tmp2
    inv Sleep,500

but it doesn't work.  Obviously this is yet another fine point of manipulating windows I just missed along the way.


   If anyone can make a suggestion on how to implement option 1 above, or can tell me what is wrong with option 2, or better still, how to lock in the positions with code, I would appreciate it.
   

sinsi

Have you had a play around with this registry key?
HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Bags\1\Desktop

I think this is where windows keeps icon positions etc - when I wrote my desktop icon program, deleting some values in the key seemed to
prevent windows from arbitrarily repositioning my icons.

Hah - almost 12 months to the day - Desktop icons and the shell - although it's not much use.
Light travels faster than sound, that's why some people seem bright until you hear them.

Jimg

Quote from: sinsi on April 12, 2008, 01:06:06 AM
Have you had a play around with this registry key?
HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Bags\1\Desktop

Yes, that's where the key FFlags is kept which determines if AutoArrange, AlignToGrid, and ShowDesktopIcons is kept.  I set that from the program so it doesn't revert to autoarrange upon bootup.

Information found at:  http://www.msfn.org/board/lofiversion/index.php/t22555.html

Auto Arrange off, Align to Grid off:
"FFlags"=dword:00000220

Auto Arrange on:
"FFlags"=dword:00000221

Auto Arrange off - align to Grid On:
"FFlags"=dword:00000224

Auto Arange on, Align to Grid on:
"FFlags"=dword:00000225

Hide Desktop Icons:
"FFlags"=dword:00001220

Sort by name:
"Sort"=dword:00000000

Sort by size:
"Sort"=dword:00000001

Sort by type:
"Sort"=dword:00000002

Sort by Modified:
"Sort"=dword:00000003

For example, if you wanted to enable auto arrange and sort by type:

[HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Bags\1\Desktop]
"FFlags"=dword:00000221
"Sort"=dword:00000002


A year ago, windows XP was much better behaved than now. 

Also, this key is for XP only.  I'm trying for a more generic solution that will work with windows 98 also.


sinsi

Have you tried deleting values ItemPos800x600(1), ItemPos1024x768(1), etc. (basically ItemPos*)? The shell seems to (re)create them at will.

To get around the abrupt repositioning, I have a save/restore program that writes/reads to a key in HKCU. I've got quite a few icons on my desktop, but
using LVS_SMALLICON fits them all, and looks cool too  :8)
Light travels faster than sound, that's why some people seem bright until you hear them.

Jimg

#4
I'm just a very positional person.  I know where the icon is supposed to be so I find them quickly and easily (although anyone else looking at my desktop couldn't understand this).

Jimg

Quote from: sinsi on April 12, 2008, 05:44:51 AM
Have you tried deleting values ItemPos800x600(1), ItemPos1024x768(1), etc. (basically ItemPos*)? The shell seems to (re)create them at will.
Yes, I've deleted the key, and XP sp2 never put it back.  It still remembers the positions and settings.  The only way I've found to make it behave is physically move an icon as I said above.  This forces the desktop to set a flag that tells the system to save all the info on shutdown.  I have not been able to find a way to set this flag in code, or even what or where this flag is.
Edit:  I take that back, on the third reboot, after I reposition the icons where I wanted them, and move an icon manually to lock it in, and rebooted, it put the key back.  Apparently this key is only used if you don't have autoalign set, and only written if you manually move an icon, and then only on shutdown.  But deleting it had no real effect.

So back to my original question--  Someone must know how to minimize all open windows so no part of the desktop is hidden so I can use the code I presented first above, or alternately, how to send the appropriate messages to the desktop listview that will make it think the user has physically moved an icon even if a windows covers the icon, as I attempted in my second chunk of code above.

xmetal

Quote from: Jimg on April 12, 2008, 05:50:40 PM
Someone must know how to minimize all open windows so no part of the desktop is hidden...

:bg


app db "Show Desktop.scf",0
.
.
.
invoke ShellExecute,0,0,addr app,0,0,0

Jimg

Quote from: xmetal on April 12, 2008, 06:37:40 PM

app db "Show Desktop.scf",0
.
.
.
invoke ShellExecute,0,0,addr app,0,0,0

You had me excited there for a moment...
All I have to do is be able to find it, since it's not in the path.

I've never done shell programming before.  The commands that do the work seem to be-
[Shell]
Command=2
[Taskbar]
Command=ToggleDesktop

So, how do I execute these with an invoke?  I don't really want to write them to a file if I don't have to.
Are these kernel32 commands?
I know just enough to get in serious trouble here.


jj2007

Quote from: Jimg on April 12, 2008, 05:50:40 PM
Someone must know how to minimize all open windows so no part of the desktop is hidden...
Press Windows key and M simultaneously.

Jimg

Funny.
Or are you suggesting invoke keybd_event?  Before I spend some more hours trying to figure that one out....
After a little searching, it looks like ÿ+M is the one wanted.  Still, how to do that with invoke keybd_event?

After hours of searching, I've found the command "Show the Desktop" as part of Explorer.exe, but I have no idea how to execute it.

MichaelW

This is a crude test that seems to work OK.

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data
      dir   db "%USERPROFILE%\Application Data\"
            db "Microsoft\Internet Explorer\Quick Launch\",0
      app   db "Show Desktop.scf",0
    .code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    invoke ExpandEnvironmentStrings, ADDR dir, 0, 0
    push eax
    mov ebx, halloc(eax)
    pop eax
    invoke ExpandEnvironmentStrings, ADDR dir, ebx, eax
   
    invoke ShellExecute, 0, 0, ADDR app, 0, ebx, 0

    hfree ebx
    inkey "Press any key to exit..."
    exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
eschew obfuscation

Jimg

Thanks Michael, I try that next.

In the meantime, I found that this works-
inv keybd_event, VK_LWIN, 0, 0, 0
inv keybd_event, VK_D, 0, 0, 0
inv keybd_event, VK_LWIN, 0, KEYEVENTF_KEYUP, 0

Both methods will have to be tried out on Windows 98 also.

MichaelW

For Windows 98 I think the environment variable USERPROFILE does not exist, but I do seem to recall a Show Desktop in the Quick Launch toolbar.

eschew obfuscation

sinsi

If you're game enough, you can use IShellDispatch, but I don't know if that includes 98.

Looking at FFlags, is it the FOLDERFLAGS enum?
Light travels faster than sound, that's why some people seem bright until you hear them.

Jimg

After looking at shell stuff for a while, I'm really starting to like the dumb send the keystrokes method.  It also works on 98.