Jump to content

C - Unusual Windows tricks


Recommended Posts

I'm looking for information on how I can do a few things in Windows XP:

1) Reserve space on the screen. Notice how when you maximize a window, it doesn't cover the taskbar because it's reserved space for itself. I need to do this but not actually put a window in the space. (I imagine it's possible, because usually if I close explorer.exe unexpectedly, the space is still reserved and I can see the desktop under it.)

2) Draw on the desktop. I don't think this should be too difficult, but I'm not entirely sure about re-drawing and the like. Examples would be appreciated.

-OR-

Create a 'true' child window on the desktop. Most of the desktop's 'children' act just like parent windows, eg Notepad, Calculator and Firefox are all children of the desktop. What I need is a window that's like part of the desktop, like the icons (if they're even windows?) or a windows' controls.

3) Get statistics about the network connection. At the very least, total amount uploaded and downloaded since startup and/or current total upload/download speed. NetLimiter does this so I don't see why I couldn't.

4) Get and set the system volume level and whether it's muted.

5) See if a given process has terminated yed. (Not the thread, the entire process.)

6) Put the system into Standby or Hibernate mode.

7) Detect when a file is written to, and what parts have been changed.

8) Get a list of icons in the system tray. I've looked all over but nobody seems to know how to do this.

9) Play system sounds (eg: Whatever sound is selected for 'Windows Startup') and add my own to the list.

10) Turn the monitor on or off.

This is actually for a few different projects I had in mind. I'll do some searching when it comes time, but I'm not really working on any of them right now :P so I just thought I'd see if anyone here knew.

Link to comment
Share on other sites


#1 in VB6...

It only changes the top of the "Desktop working area" (I used it to poof those client ISP ad banners)

Private Declare Function SetWindowPos Lib "user32" (ByVal Hwnd As Long, ByVal hWndInsertAfter As Long, ByVal X As Long, ByVal Y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Private Declare Function GetWindowRect Lib "user32" (ByVal Hwnd As Long, lpRect As RECT) As Long
Private Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" (ByVal uAction As Long, ByVal uParam As Long, ByRef lpvParam As Any, ByVal fuWinIni As Long) As Long
Private Declare Function IsWindowVisible Lib "user32" (ByVal Hwnd As Long) As Long
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal Hwnd As Long, ByVal nIndex As Long) As Long

Public Sub DesktopSetWorkArea(NewTop&)
Dim wa As RECT, spir&
Dim h&, wl&, wr As RECT

spir = SystemParametersInfo(SPI_GETWORKAREA, 0, wa, 0)
If spir = 0 Then Exit Sub
wa.Top = NewTop
SystemParametersInfo SPI_SETWORKAREA, 0, wa, SPIF_SENDWININICHANGE

Do
   h = FindWindowEx(0, h, vbNullString, vbNullString)
   If h = 0 Then Exit Do
   
   If IsWindowVisible(h) <> 0 Then
       wl = GetWindowLong(h, GWL_STYLE)
       If (wl And WS_MAXIMIZE) = WS_MAXIMIZE Then
           GetWindowRect h, wr
           wr.Top = NewTop
           SetWindowPos h, 0, wr.Left, wr.Top, wr.Right - wr.Left + 1, wr.Bottom - wr.Top + 1, SWP_NOACTIVATE Or SWP_NOZORDER
       Else
           If NewTop <> 0 Then
               GetWindowRect h, wr
               If wr.Top < NewTop Then
                   SetWindowPos h, 0, wr.Left, NewTop, 0, 0, SWP_NOACTIVATE Or SWP_NOZORDER Or SWP_NOSIZE
               End If
           End If
       End If
   End If
Loop
End Sub

Link to comment
Share on other sites

3: network statistics

?

4: volume level

Maybe this could help, since I don't do very much C++:

http://www.codeguru.com/Cpp/G-M/multimedia...icle.php/c1567/

5: process has terminated

Use EnumProcesses. If you didn't directly ran the program with CreateProcess, I think it gives you a handle you can use to

check its status.

6: Put the system into Standby or Hibernate mode

VB6...

ExitWindows <flags>, &HFFFFFFFF

Replace the <flags> with one or more of the following flags:

Const EWX_LogOff = 0&

Const EWX_SHUTDOWN = 1&

Const EWX_REBOOT = 2&

Const EWX_FORCE = 4&

7: Detect when a file is written to

(last modified date?)

Probably the FindFirstChangeNotification API

8: Get a list of icons in the system tray

I wrote a program to run before the taskbar did, and superclass the tray window before it was created. By doing this and monitoring what messages were received, it could tell what icons were there. The program's purpose was to be able to put back all the icons if/when the tray locked up and was restarted. It has a minor bug with WinXP, but then again, WinXP's taskbar never locks up. I'd be glad to post the program here if you would like it. (VB6 + the core C++ dll) Again, it must be run before the taskbar for it to work.

9: Play system sounds

These are stored in the registry: HKCU\AppEvents\Schemes\Apps\.Default

That's all I know about it.

10: Turn the monitor on or off

PostMessage <hwnd>, WM_SYSCOMMAND, SC_MONITORPOWER, <flag>

<flag> can be one of these:

Const MONITOR_ON = -1&

Const MONITOR_LOWPOWER = 1&

Const MONITOR_OFF = 2&

<hwnd> can be any valid window handle. They should all respond the same way.

11: How to blue screen an NT computer

Key: HKLM\SYSTEM\CurrentControlSet\Services\i8042prt\Parameters

Value (dw): "CrashOnCtrlScroll" = 1

Reboot

Ctrl-ScrlLock twice

Link to comment
Share on other sites

Thanks, some helpful stuff. Some questions about a few though:

2: Aren't all parent windows set to have the desktop as their parent already? MSDN always refers to them as children of the desktop. O_o

6: That doesn't seem to cover standby or hibernate. They seem to be rather elusive, shutdown.exe doesn't do them either.

7: What I meant by this is if I have a file open and another program modifies it, I need to know what section was modified (or at least some notice of the change). I think just checking the access date resets it. (Brilliant design! :thumbdown)

8: I'm not sure that'll work. The idea is that when this program is running, explorer.exe won't be at all. It only needs to work for XP though.

11: Not sure why you included that, but yeah. O_o Know a way to do it through code at all? :P

Link to comment
Share on other sites

2: Aren't all parent windows set to have the desktop as their parent already? MSDN always refers to them as children of the desktop. O_o

This is what Spy++ shows for the structure on Windows XP. I hope I made some sense out of it all. :}

#"":"#32769" <-- This is the handle the GetDesktopWindow API returns, and is what the MSDN refers to as the "desktop"

--#"ZoneAlarm":"#32770"

--#"MSFN Forums -> Replying...":"MozillaWindowClass"

--#"Diskeeper Service":"DkService Class"

--#"Program Manager":"Progman" <-- This is what we think of as the "desktop" (the wallpaper and icons)

----#"":"SHELLDLL_DefView"

------#"FolderView":"SysListView32"

--------#"":"SysHeader32"

------#"":"Internet Explorer_Server" <-- If there are NO web items shown, and desktop icons ARE shown, then this is not here

--------#"":"Shell Embedding" <-- This is an optional web item I added to my desktop

----------#"":"Shell DocObject View"

------------#"":"Internet Explorer_Server"

--------#"":"Shell Embedding" <-- This is an optional web item I added to my desktop

----------#"":"Shell DocObject View"

------------#"":"Internet Explorer_Server"

--------#"":"DeskMover"

--#Progman is usually the last window, but there may be more top level windows...

Now keep in mind that the "Progman" belongs to explorer.exe, so if the taskbar gets shutdown, it goes with it. Without the taskbar, there is no such thing as a window fixed behind all other windows. All are top-level then.

Also, if the desktop refreshes itself (by showing/hiding icons, adding a web item, etc.) The only windows which don't get recreated are the "Progman", "SHELLDLL_DefView", and the "SysListView32" (and anything under that).

If the desktop icons are hidden, the desktop does this by hiding the "SysListView32". If you want your custom window to hide with the icons, set its parent to that "SysListView32", otherwise set its parent to the "SHELLDLL_DefView". The negative to that last option is that if the icons are hidden and then shown, your window gets shoved to the bottom of the zorder and essentially hidden. I'm not sure how to get around that. There may be some API to bring it back to the front.

Link to comment
Share on other sites

6: That doesn't seem to cover standby or hibernate. They seem to be rather elusive, shutdown.exe doesn't do them either.

Sorry. :wacko: Your right.

Use this for hibernating: SetSystemPowerState(0, False)

And this for suspending: SetSystemPowerState(1, False)

Before you do either one, your program must adjust its privileges (for shutting down and logging off, you don't need this.)...

Sub AdjustToken()
   Const TOKEN_ADJUST_PRIVILEGES = &H20
   Const TOKEN_QUERY = &H8
   Const SE_PRIVILEGE_ENABLED = &H2
   Dim hdlProcessHandle As Long
   Dim hdlTokenHandle As Long
   Dim tmpLuid As LUID
   Dim tkp As TOKEN_PRIVILEGES
   Dim tkpNewButIgnored As TOKEN_PRIVILEGES
   Dim lBufferNeeded As Long
   
   hdlProcessHandle = GetCurrentProcess()
   OpenProcessToken hdlProcessHandle, (TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY), hdlTokenHandle

   ' Get the LUID for shutdown privilege
   LookupPrivilegeValue "", "SeShutdownPrivilege", tmpLuid
   tkp.PrivilegeCount = 1  ' One privilege to set
   tkp.TheLuid = tmpLuid
   tkp.Attributes = SE_PRIVILEGE_ENABLED
   
   ' Enable the shutdown privilege in the access token of this process
   AdjustTokenPrivileges hdlTokenHandle, False, tkp, Len(tkpNewButIgnored), tkpNewButIgnored, lBufferNeeded
End Sub

Link to comment
Share on other sites

7: What I meant by this is if I have a file open and another program modifies it, I need to know what section was modified (or at least some notice of the change). I think just checking the access date resets it. (Brilliant design!)
If you have the file open, you can just open it with LOCK_WRITE to stop any other program from changing it. If you do want to let others change it, try that API I gave you (FindFirstChangeNotification). I've never used it, so I don't know how.
8: I'm not sure that'll work. The idea is that when this program is running, explorer.exe won't be at all. It only needs to work for XP though.

Are you, like, trying to make your own taskbar, your own program to respond to the Shell_NotifyIcon? I don't know how to do that, but if MS can, I don't see why it is not possible.

11: Not sure why you included that, but yeah. O_o Know a way to do it through code at all?

Just thought it was fun. You could write a purposely faulty driver, though. :D

Maybe you should start a separate post for 7 and 8. The bystanders must think I have the solution to all 10 of them, but I really don't.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...