21. februar 2004 - 20:16Der er
6 kommentarer og 1 løsning
Ændre rækkefølgen af åbne vinduer
Er det muligt via kode at ændre rækkefølgen af de åbne vinduer (dem man ser nederst i proceslinien)?
Jeg ved, det er muligt at hente en liste over de åbne vinduer, men jeg kunne godt tænke mig at ændre i rækkefølgen således, at jeg kan flytte et åbent vindue frem og tilbage på proceslinien.
Hvis det overhovedet er muligt, ville det også være rart med noget kode.
Som programmøren selv skriver, så er der tilsyneladende ingen måde at lege direkte med processlinien. Det løses ved at lukke og åbne de fundne vinduer i den rækkefølge som de skal vises i listen. Det flimrer lidt, men det virker.
Har lige kopieret koden ud (det er ulæseligt men det er fordi det er C++ syntaks ;-))
int nNumItems = m_listWindows.GetCount(); for (int n = 0; n < nNumItems; n++) { HWND hwnd = (HWND)m_listWindows.GetItemData(n); ::ShowWindow(hwnd, SW_HIDE); ::ShowWindow(hwnd, SW_SHOW); } // now hide and show self ShowWindow(SW_HIDE); ShowWindow(SW_SHOW); SetForegroundWindow();
Spøg til side (men C++ syntaksen er altså slem), så findes ShowWindow i Dwlphi, så det sværeste er at skaffe en liste af vinduer. Her gennemsøger han alle og tager de der ikke har en owner => de er main-applikationen. Funktioenen er vist nedenfor:
/*static */BOOL CALLBACK CTaskbarSortDlg::ListWindows(HWND hwnd, LPARAM lparam) { // lParam is the dialog BOOL bRetVal = TRUE; CTaskbarSortDlg* pDlg = (CTaskbarSortDlg*)lparam; char *lpsz; int nTitleLength; int nIndex;
// tried: IsWindow(hwnd) - didn't filter out any // tried: IsWindowEnabled(hwnd) - filtered out threads (OLE etc) if (hwnd == pDlg->GetSafeHwnd()) { // don't process this window TRACE0("This window!\n"); } else if (::GetParent(hwnd) != NULL) // owned - won't be in taskbar { //TRACE0("Owned window\n"); } else if (::GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW) { //TRACE0("Window is a tool window\n"); } else if (!::IsWindowVisible(hwnd)) { //TRACE0("Window not visible\n"); } else if ((nTitleLength = ::GetWindowTextLength(hwnd)) == 0) { // no title! //TRACE0("Window has no title\n"); } else { nTitleLength++; lpsz = new char[nTitleLength]; if (::GetWindowText(hwnd, lpsz, nTitleLength) == 0) { // must be an error! TRACE0("Error getting window text\n"); bRetVal = FALSE; } else if (stricmp(lpsz, "Program Manager") != 0) { if ((nIndex = pDlg->m_listWindows.AddString(lpsz)) == LB_ERR) { TRACE0("Error adding string\n"); } else if (nIndex == LB_ERRSPACE) { // out of room - fatal error TRACE0("Error adding string: no room\n"); bRetVal = FALSE; } else if (pDlg->m_listWindows.SetItemData(nIndex,(DWORD)hwnd) == LB_ERR) { TRACE0("Error setting item data\n"); } } delete lpsz; } return bRetVal; }
Jeg søgte lidt videre på nettet og fandt et eksempel som jeg tilrettede til følgende:
function FindWindows(aWindows: TStrings): longint; const StLgd = 255; var hWndCurWin, hWndDesk: HWnd; szWinText: pChar; WinText: string; foundAt: byte; bNoGo : boolean; begin result := -1; hWndDesk:= GetDesktopWindow;
aWindows.Clear;
{This ist the parent of alle top-level windows} if hWndDesk <> 0 then hWndCurWin := GetWindow(hWndDesk,GW_CHILD) else {place error handling here} exit;
if not assigned(aWindows) then exit; {you have to create Stringlist before passing the variable to this function}
getMem(szWinText,StLgd+1); try while (hWndCurWin <> 0) do begin GetWindowText(hWndCurWin, szWinText,StLgd);
bNoGo := false; WinText:= strpas(szWinText); if GetParent(hWndCurWin) <> 0 then // Parents bNoGo := true;
if ((GetWindowLong(hWndCurWin, GWL_EXSTYLE) and WS_EX_TOOLWINDOW) <> 0) then // Tool window bNoGo := true;
if IsWindowVisible(hWndCurWin) then // Visible bNoGo := true;
if WinText = '' then // No title bNoGo := true;
if not bNoGo then aWindows.AddObject(WinText,TObject(hWndCurWin));
Der kommer lidt for mange vinduer til, men det er fremskridt. Bemærk, i øvrigt at hver linie i TStrings (eller en nedarving af) indeholder handle til vindue i aWindows.Lines.Objects[index] - den er altså let at få fat på når du skal fjerne og sætte den igen.
Ok, tak, har prøvet programmet og det virker sådan som jeg ønsker det.
Nu er det bare sådan, at jeg gerne vil have sourcekoden konverteret til Delphi, så jeg kan lave min egen version af programmet, og jeg kender næsten intet til C++ (jeg forstår næsten ingenting af koden foroven).
Jeg vil høre, om det på en eller anden måde er muligt på en (forholdsvis) nem måde at få koden lavet om til brugbar Delphi kode, eller om nogle af jer super programmøre derude evt. gider at skrive Delphi koden.
Jeg vil gerne smide nogle flere point i, hvis det er.
Er det bare kernen i programmet eller skal det ligne det? For kernen er mere eller mindre ovenfor. Jeg skal gerne prøve at strikke noget sammen til dig - gi' mig lige en dags tid.
Jeg takker mange gange for din hjælp, har leget lidt med det og fået det til at virke. Jeg håber bare en dag, at jeg også kan få ikonerne med for hvert vindue i listen.
Jeg er desværre ikke kommet direkte videre, men har rodet en del med andre ting der måske kan bruges - vender nok tilbage snart. Problemet med det eksempel jeg konverterede til Delphi er, at det var baseret på MFC-klasserne (klasser, ha! Sgu ikke objektklasser ;-)) og det lykkes mig ikke at gøre noget tilsvarende i Delphi.
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.