Assembly code snippets

Back to the snippets overview

Details

TitleRe-ordering taskbar items
AuthorThomas
Submitted by:Thomas
Date added:2002-02-17 21:20:39
Date modified:2002-02-17 21:20:39

Comments

Win NT/2k only!

This code shows how to change the order of the taskbar items. It does this by allocating memory in explorer's process (this can only be done in NT), reading the taskbar items (which basically is a tab window), reversing their order, and setting them again.
This example reverses the order, you can use any order you like though.
The int 3 opcodes are for generating a debugger breakpoint if anything goes wrong. Replace them with your error handling code.

Snippet

.data
tShTrayWnd      db  "Shell_TrayWnd",0
tRebarCtrl      db  "ReBarWindow32",0
tTaskSwClass    db  "MSTaskSwWClass",0
tSysTabCtrl     db  "SysTabControl32",0

.code

MAX_TEXT_BUFFERSIZE     equ     500

MoveTaskBarItems    proc uses ebx edi esi
LOCAL   tbiCount:DWORD
LOCAL   hTaskBar:DWORD
LOCAL   explorerPID:DWORD
LOCAL   hExplorer:DWORD
LOCAL   tempItem:TC_ITEM
LOCAL   BytesWritten:DWORD

    invoke  FindWindowEx, 0, 0, addr tShTrayWnd, NULL
    .IF     !eax
        int 3
    .ENDIF

    invoke  FindWindowEx, eax, NULL, addr tRebarCtrl, NULL
    .IF     !eax
        int 3 ;no taskbar tab control found?
    .ENDIF

    invoke  FindWindowEx, eax, NULL, addr tTaskSwClass, NULL
    .IF     !eax
        int 3 ;no taskbar tab control found?
    .ENDIF

    invoke  FindWindowEx, eax, NULL, addr tSysTabCtrl, NULL
    .IF     !eax
        int 3 ;no taskbar tab control found?
    .ENDIF

    mov     hTaskBar, eax
    lea     ecx, explorerPID
    invoke  GetWindowThreadProcessId, eax, ecx

    ; --- Open explorer process ---
    invoke  OpenProcess, PROCESS_VM_OPERATION OR PROCESS_VM_WRITE, FALSE, explorerPID
    .IF     !eax
        int 3
    .ENDIF
    mov     hExplorer, eax

    ; --- get number of items on taskbar ---
    invoke  SendMessage, hTaskBar, TCM_GETITEMCOUNT, 0, 0
    or      eax, eax
    jz      @no_items

    mov     tbiCount, eax

    ; --- items * (sizeof TC_ITEM) + size of text buffer ---
    mov     ecx, (SIZEOF TC_ITEM)+ MAX_TEXT_BUFFERSIZE
    mul     ecx

    ; --- allocate memory in memory space of explorer ---
    invoke  VirtualAllocEx, hExplorer, NULL, eax, MEM_COMMIT, PAGE_READWRITE

    ; Note: the allocated memory is an array of (TC_ITEM + TextBuffer)s.
    ; The textbuffer is necessary to store the texts on the items

    mov     edi, eax
    mov     esi, eax

    ; tempitem is copied into each item before retrieving info
    mov     tempItem.imask, TCIF_TEXT OR TCIF_IMAGE OR TCIF_PARAM

    xor     ebx, ebx
    .WHILE  ebx<tbiCount

        ; --- let eax point to the text buffer ---
        mov     eax, esi
        add     eax, SIZEOF TC_ITEM

        ; --- store pointer to textbuffer & size in tempItem ---
        mov     tempItem.pszText, eax
        mov     tempItem.cchTextMax, MAX_TEXT_BUFFERSIZE

        ; --- Write this into memory space of explorer ---
        invoke  WriteProcessMemory, hExplorer, esi, addr tempItem, SIZEOF TC_ITEM, \
                    addr BytesWritten

        ; --- Get item info ---
        invoke  SendMessage, hTaskBar, TCM_GETITEM, ebx, esi

        ; --- move to next item in array ---
        add esi, (SIZEOF TC_ITEM)+ MAX_TEXT_BUFFERSIZE
        inc ebx
    .ENDW

    ; --- delete everything ---
    invoke  SendMessage, hTaskBar, TCM_DELETEALLITEMS, 0, 0

    mov     esi, edi

    xor     ebx, ebx
    .WHILE  ebx<tbiCount
        ; --- get itemcount-currentcounter-1 = new index ---
        mov     eax, tbiCount
        dec     eax
        sub     eax, ebx
        xor     eax, eax

        ; --- place item back ---
        invoke  SendMessage, hTaskBar, TCM_INSERTITEM, eax, esi

        ; --- move to next item in array ---
        add esi, (SIZEOF TC_ITEM) + MAX_TEXT_BUFFERSIZE
        inc ebx
    .ENDW

    ; --- free memory ---
    invoke  VirtualFreeEx, hExplorer, edi, 0, MEM_RELEASE

   @no_items:
    invoke  CloseHandle, hExplorer
ret
MoveTaskBarItems endp