Jak zjistit o kolik okno přesahuje mimo viditelnou část obrazovky? Mám dvě okna v aplikaci. Když otevřu mapu, tak mi okno s mapou o přesahuje obrazovku a tak chci vypočítat novou pozici pro obě okna.
Fórum › C / C++
Jak zjistit o kolik okno přesahuje?
#1 oxidián
Zjisti si aktuální rozlišení monitoru, zjisti si pozici a velikost okna (pozice se většinou váže k levému hornímu rohu okna od levého horního rohu pracovní plochy), přičti k pozici šířku a výšku okna, porovnej, zda je přičtená šířka nebo výška větší než zjištěné rozlišení monitoru a máš přesah.
Všechno se dá zjistit přes WinAPI.
#1 oxidián
Takhle nějak zjistíš pracovní oblast obrazovky/monitoru:
RECT rect_work;
if (primarni_monitor)
{
if (!SystemParametersInfo(SPI_GETWORKAREA, 0, &rect_work, 0))
kriticke_ukonceni();
}
else
{
HMONITOR hmonitor = MonitorFromWindow(hwnd_, MONITOR_DEFAULTTONEAREST);
_ASSERTE(hmonitor != nullptr);
if (hmonitor == nullptr)
kriticke_ukonceni();
MONITORINFOEX mi;
memset(&mi, 0, sizeof(mi));
mi.cbSize = sizeof(mi);
if (!GetMonitorInfo(hmonitor, &mi))
{
if (!SystemParametersInfo(SPI_GETWORKAREA, 0, &rect_work, 0))
kriticke_ukonceni();
}
else
memcpy(&rect_work, &mi.rcWork, sizeof(rect_work));
}
a pak potřebuješ GetWindowRect pro zjištění polohy a rozměrů okna
pak trochu počítání souřadnic
a nakonec (v připadě potřeby) zavolat fci SetWindowPos
Radek Chalupa
- individuální konzultace, školení programování (C/C++, WinAPI, COM, ActiveX, ATL, C#, NET Framework, MFC)
- vývoj software na zakázku
http://www.radekchalupa.cz
Teď už to mám hotové. Ale je tu malinký zádrhel a tak bych se vás chtěl zeptat jestli nevíte v čím to je.
void OnMAP_Reset(HWND mapview, bool resize)
{
if (resize)
{
RECT MapView, MainWind, Desktop;
const HWND hDesktop = GetDesktopWindow();
// get bounding rectangle of window (client area)
GetWindowRect(mapview, &MapView);
GetWindowRect(wrapper.handles.hPropSheet, &MainWind);
GetWindowRect(hDesktop, &Desktop);
// JUST FOR INTEREST:
RECT rcClient;
POINT border;
GetClientRect(mapview, &rcClient); // get size of Window
border.x = (MapView.right - MapView.left) - rcClient.right;
border.y = (MapView.bottom - MapView.top) - rcClient.bottom;
int border_width = border.x/2;
int title_height = border.y-border.x;
// int mapViewWidth = MapView.right; // INCORRECT! USE minsize
int mainWindWidth = MainWind.right-MainWind.left;
int screenWidth = Desktop.right;
int screenHeight = Desktop.bottom;
int posx = 0;
int posy = 0;
POINT minsize = CalculateMinSize(mapview);
// The rest of screen is bigger than width of Map Viewer
if (screenWidth - mainWindWidth >= minsize.x)
{
posx = (int) ((screenWidth - mainWindWidth - minsize.x) / 3);
SetWindowPos(wrapper.handles.hPropSheet, NULL, posx, posy, 0, 0,
SWP_NOSIZE | SWP_NOZORDER);
posx = (int) ((screenWidth - mainWindWidth - minsize.x) / 3 * 2 + mainWindWidth);
SetWindowPos(mapview, NULL, posx, posy, minsize.x, minsize.y,
SWP_NOZORDER);
}
else
{
SetWindowPos(wrapper.handles.hPropSheet, NULL, 0, posy, 0, 0,
SWP_NOSIZE | SWP_NOZORDER);
// If the windows cannot fit screen, shit the Map Viewer a bit to left (overlap main window)
posx = mainWindWidth + minsize.x > screenWidth ? mainWindWidth -
(-screenWidth+mainWindWidth+minsize.x>=41?41:(-screenWidth+mainWindWidth+minsize.x) )
: mainWindWidth;
SetWindowPos(mapview, NULL, posx, posy, minsize.x, minsize.y,
SWP_NOZORDER);
}
posx = (screenWidth - mainWindWidth - minsize.x) / 3;
}
// Erase everything and re-draw
HandleRefresh(mapview, TRUE);
}
CalculateMinSize spolehlivě vrátí velikost okna, kterou potřebuji.
Mám rozlišení 800 x 600 px. Hlavní okno je obdelníkové na ležato a je vlevo, druhé okno má být vpravo vedle něj a je čtvercové + statusbar. Nejdříve otevřu malou mapu, ta se krásně vleze na obrazovku, skočí to tedy do první větve if a pozice obou oken se upraví tak, aby byly okna rovnoměrně od sebe. Pak otevřu větší mapu (dojde k aktualizaci rozměru okna a načte se jiný obrázek do okna č. 2), větší čtverec (okno) se nevleze na obrazovku, takže hlavní okno má souřadnici x = 0 a souřadnice x u pravého okna je šířka hlavního okna (č. 1) mínus cca 40px. Takže dokde k překryvu oken. Pak znovu načtu první mapu a ejhle, rozměr okna asi není ten samý co byl, i když hodnoty ukazují stejnou hodnotu minsize (první větev, druhý řádek). Jde o to, že okno se jeví jakoby trochu zmenšené takže se mapka nevleze do okna a tj. asi ořez 20px zprava a 20px dole. U toho prvního okna nebyly posuvníky, teď se tam ale posuvníky objevily a já nechápu proč. Takže při spuštění programu a otevření malé mapky posuvníky tam nejsou. Po otevření další mapky a znovu otevření první mapky tam jsou posuvníky. Ty posuvníky asi ořízly mapku. Otázka je proč tam jsou posuvníky? Potažmo jak se jich zbavit?
V proceduře dlgproc toho okna MapView jsou mimo jiné tyto věci:
case WM_SIZE:
UpdateScrollbars(window, LOWORD(lParam), HIWORD(lParam));
SendMessage(data.statusbar, WM_SIZE, 0, 0);
break;
case WM_HSCROLL:
OnWM_HSCROLL(window, LOWORD(wParam), HIWORD(wParam));
break;
case WM_VSCROLL:
OnWM_VSCROLL(window, LOWORD(wParam), HIWORD(wParam));
break;
Už jsem zjistil co zapíná ty scrollbary:
posx = (int) ((screenWidth - mainWindWidth - minsize.x) / 3 * 2 + mainWindWidth);
SetWindowPos(mapview, NULL, posx, posy, minsize.x, minsize.y,
SWP_NOZORDER);
SetWindowPos. Jak to udělat, aby se scrollbary nezapnuly? Otevírám jednu a tu samou mapu, která by se měla vejít do okna (rozměr okna je stejný, stejná mapa) ale přesto se tam vytvoří scrollbary. Testem na strukturu SCROLLBARINFO jsem zjistil že pSBI->rgstate[0] == STATE_SYSTEM_INVISIBLE je v prvním případě true, v druhém false. Takže SetWindowPos změní tu informaci, takže musí existovat flag kterým to STATE_SYSTEM_INVISIBLE nevypínat. Jinak bych snad mohl nastavit SCROLLINFO si; SetScrollInfo(window, SB_HORZ, &si, FALSE);
Přidej příspěvek
Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku
×Vložení zdrojáku
×Vložení obrázku
×Vložení videa
Uživatelé prohlížející si toto vlákno
Podobná vlákna
Makro pro Word: Jak zjistit jestli je vybraný text a jak nastavit sc… — založil oxidián
Jak zjistit IP adrsu PC — založil machis
Jak zjistit soubory — založil XRobotRobocop
Jak zjistit jmeno PC? — založil machis
Jak zjistit přetečení? — založil
Moderátoři diskuze