[Win32] Virtuele desktop positie van window *

Pagina: 1
Acties:

  • Sponge
  • Registratie: Januari 2002
  • Laatst online: 01-12 17:59

Sponge

Serious Game Developer

Topicstarter
Ik ben bezig met een projectje in VC2003, en ben nu aangekomen bij een lastig probleem. Ik heb namelijk de virtuele desktop positie nodig. Bij een enkele monitor is dit bijvoorbeeld 0,0 - 1024,768, maar bij een multi monitor setup zou dit bijvoorbeeld 0,0 - 2048,768 kunnen zijn.

de WM_MOVE event geeft de coordinaten terug van de "huidige" monitor waar het venster op dat moment op/naar versleept is. Nu heb ik al aardig wat geexperimenteerd met stukjes code zoals:

code:
1
2
3
        WINDOWPLACEMENT wp;
        wp.length = sizeof(WINDOWPLACEMENT);
        GetWindowPlacement( &wp );


Deze gebruikt echter ook gewoon de huidige monitor.

code:
1
        HMONITOR hMonitor = ::MonitorFromPoint( CPoint(x, y), MONITOR_DEFAULTTONEAREST );


Geeft de monitor aan, maar je weet helaas niet wat de volgorde is van de monitoren (2 - 1 , 1 - 2, of misschien ook nog op de Y as?)

Bovenstaande + het volgende:

code:
1
2
3
4
5
6
7
8
9
10
11
12
        // Get the monitor info
        MONITORINFO monInfo;
        monInfo.cbSize = sizeof(MONITORINFO);
        if(::GetMonitorInfo( hMonitor, &monInfo )==0)
        {
            //AfxMessageBox("GetMonitorInfo failed");
            //return(FALSE);
        }

        // Adjust for work area
        x += monInfo.rcWork.left - monInfo.rcMonitor.left;
        y += monInfo.rcWork.top  - monInfo.rcMonitor.top;


Geeft uiteraard ook weer heel mooi de coordinaten, van de huidige monitor. De uitkomst is dan ook precies hetzelfde als wat x en y al waren meende ik.

code:
1
        int virtualscreen = GetSystemMetrics (SM_CXVIRTUALSCREEN );


Geeft heel mooi 2560 aan (2x 1280), maar ja, daar heb ik helaas weinig aan.

Het enige wat ik kan bedenken is om zelf de virtuele desktop te berekenen door alle monitoren te enumereren die actief zijn, en dan met GetMonitorInfo bijvoorbeeld de volgorde te bepalen (via de min/max waardes), en om dan uiteindelijk daarmee de echte virtuele positie te berekenen. Helaas klinkt dit a) omslachtig en b) fout gevoelig.

Dus ik vroeg me af of iemand hier nog suggesties heeft qua API calls misschien? of andere ideeen?

  • Patriot
  • Registratie: December 2004
  • Laatst online: 19:06

Patriot

Fulltime #whatpulsert

Ik heb geen suggesties op script niveau, maar het lijkt mij dat monitor 2 altijd de monitor is waarnaar het bureaublad wordt uitgebreid, en dat monitor 1 gewoon de monitor is waar de startknop ook zit (bwvs).

Of die twee monitoren dan onder of boven elkaar geplaatst worden is ook het probleem niet, lijkt mij.

  • Sponge
  • Registratie: Januari 2002
  • Laatst online: 01-12 17:59

Sponge

Serious Game Developer

Topicstarter
Helaas bij mij is de setup bijvoorbeeld 2 - 1 (primary). Als mijn programma zijn positie ophaalt, is dat bijvoorbeeld 600,400. Dat zijn de coordinaten voor de huidige monitor (primary, dus rechts), in principe zou het namelijk (1280+600),400 moeten zijn.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 14:52

.oisyn

Moderator Devschuur®

Demotivational Speaker

Sponge schreef op woensdag 06 december 2006 @ 22:53:
de WM_MOVE event geeft de coordinaten terug van de "huidige" monitor waar het venster op dat moment op/naar versleept is.
:? Screen coordinates zouden gewoon hetzelfde als desktop coordinates moeten zijn hoor.
Ik heb ook een 2-1 opstelling, en mijn primary monitor draait een hogere resolutie (1600x1200 vs 1280x1024). Mijn desktop loopt in principe van (-1280, 0) tot (1600,1200), en in het gebied (-1280, 0) tot (0, 176) zit niets omdat mijn linker monitor onder uitgelijnd is.

Als ik een window move krijg ik ook gewoon dergelijke coordinaten terug.

Als je per se de rectangle van een monitor in desktop coordinates wil weten moet je GetMonitorInfo() aanroepen.

[ Voor 7% gewijzigd door .oisyn op 06-12-2006 23:27 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Sponge
  • Registratie: Januari 2002
  • Laatst online: 01-12 17:59

Sponge

Serious Game Developer

Topicstarter
Dat hangt ook deels van de videokaart af. Sommige videokaarten werken zonder Dual head en hebben inderdaad een grote desktop, ipv. "twee desktops". Overigens zie ik inderdaad dat de linkerscherm een muis positie van -455 geeft bijvoorbeeld. Snap niet waarom me dat niet opgevallen is ;). Echter, ik werk op het desktop niveau (SysListview32 class). En die werkt helaas met 0,0 - 2560,1024.


Maar nu ik dit zo zeg realiseer ik me dat ik dit makkelijk op kan lossen met ScreenToClient... en dat werkt perfect!

Mja, los ik het probleem gewoon binnen een minuut op, en werkt alles ook meteen perfect :). Bedankt allemaal :). Soms helpt het even om een second opinion te krijgen ;).

  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 01-12 21:29

Tomatoman

Fulltime prutser

Wist je trouwens dat je in Delphi en Borland C++ de globale Monitors variabele hebt? Dat scheelt je wellicht weer wat code om de individuele monitors te benaderen.

Nog even over de monitorindeling: monitoren kunnen in principe willekeurig worden geplaatst en willekeurige (van elkaar verschillende) resoluties hebben, zolang ze maar maar ergens aan elkaar grenzen. De primaire monitor heeft als linkerbovenhoek altijd (0,0). Stel dat die monitor loopt van (0,0) tot (1280,1024). Als je daar links een monitor naast zet met een resolutie van 800x600 en je zet hem een beetje hoog, dan kan het best zijn dat die als coordinaten heeft (-800,-150) tot (-1,649).

Als je vervolgens een screenshot maakt van de complete desktop, zul je zien dat je een plaatje krijgt dat 800 + 1280 = 2080 pixels breed is en 150 + 1024 = 1154 pixels hoog is. Linksonder en rechtsboven zal de screenshot een zwart gebied hebben.

Een goede grap mag vrienden kosten.

Pagina: 1