|
12.07.2011, 23:30
|
#1
|
Зануда с интернетом
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений (для 20,935 пользователей)
|
GetWindowRect
Забодал этот косяк: как окна центровать - так пиши костыли.
Вот что написано во всех мануалах:
Функция GetWindowRect отыскивает размеры рамки ограничивающей прямоугольник определяемого окна. Размеры даны в экранных координатах, которые расположены относительно левого верхнего угла экрана.
|
Безусловно - поля bottom и right содержат в себе координаты y и x правой нижней точки окна. Проблема в том, что left и top содержат нули.
Ну т.е. для окна с левым верхним углом в 100;50 и размерами 100;100,
результат будет
left=0
top=0
bottom=150
right=200
Ну блин!
Т.е. функция ведёт себя аналогично GetClientRect (которая возвращает координаты в системе отсчёта рабочей области).
Оценить левый угол, исходя из разности GetClientRect и GetWindowRect нельзя, т.к. в уравнении участвуют ещё неизвестные параметры, характеризующие толщину границы окна, шапку (её может и не быть), системное меню, статус бар и прочее.
При этом в кодах разных прогеров часто встречается код, подразумевающий именно такой результат работы, как описан в учебнике.
Запускаю отладку - нули.
ЧЯДНТ?
mfc: http://www.firststeps.ru/mfc/winapi/r.php?72
!mfc: http://vsokovikov.narod.ru/New_MSDN_...windowrect.htm
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
|
(Offline)
|
|
13.07.2011, 02:52
|
#2
|
Дэвелопер
Регистрация: 06.04.2009
Адрес: Запорожье
Сообщений: 1,500
Написано 1,011 полезных сообщений (для 4,642 пользователей)
|
Ответ: GetWindowRect
Если нужно отцентрировать окно, то сначала получаешь его размеры (у тебя уже есть).
Затем получаешь размер декстопа:
int dx = GetSystemMetrics(SM_CXSCREEN);
int dy = GetSystemMetrics(SM_CYSCREEN);
Центрируешь:
int x = (dx - width) >> 1;
int y = (dy - height) >> 1;
SetWindowPos(rWnd, HWND_TOP, x, y, width, height, SWP_SHOWWINDOW);
__________________
|
(Offline)
|
|
Эти 2 пользователя(ей) сказали Спасибо .Squid за это полезное сообщение:
|
|
13.07.2011, 04:25
|
#3
|
[object Object]
Регистрация: 01.08.2008
Адрес: В России
Сообщений: 4,359
Написано 2,473 полезных сообщений (для 6,856 пользователей)
|
Ответ: GetWindowRect
Сообщение от .Squid
int x = (dx - width) >> 1;
int y = (dy - height) >> 1;
|
Что означает конструкция ">> 1"?
__________________
Retry, Abort, Ignore? █
Intel Core i7-9700 4.70 Ghz; 64Gb; Nvidia RTX 3070
AMD Ryzen 7 3800X 4.3Ghz; 64Gb; Nvidia 1070Ti
AMD Ryzen 7 1700X 3.4Ghz; 8Gb; AMD RX 570
AMD Athlon II 2.6Ghz; 8Gb; Nvidia GTX 750 Ti
|
(Offline)
|
|
13.07.2011, 05:55
|
#4
|
Дэвелопер
Регистрация: 06.04.2009
Адрес: Запорожье
Сообщений: 1,500
Написано 1,011 полезных сообщений (для 4,642 пользователей)
|
Ответ: GetWindowRect
Бинарный сдвиг вправо на указанное число битов.
__________________
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
13.07.2011, 10:33
|
#5
|
Зануда с интернетом
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений (для 20,935 пользователей)
|
Ответ: GetWindowRect
Сообщение от .Squid
Если нужно отцентрировать окно, то сначала получаешь его размеры (у тебя уже есть).
Затем получаешь размер декстопа:
int dx = GetSystemMetrics(SM_CXSCREEN);
int dy = GetSystemMetrics(SM_CYSCREEN);
Центрируешь:
int x = (dx - width) >> 1;
int y = (dy - height) >> 1;
SetWindowPos(rWnd, HWND_TOP, x, y, width, height, SWP_SHOWWINDOW);
|
НУ, собственно - так и собирался (только размеры декстопа через его дескриптор хотел GetDesktopWindow). Но всё равно костыли - размеры окна своего придётся либио фиксировать либо кажный раз править исходник (т.к. GetWindowRect примешивает к размерам ещё и смещение левого края, а GetClientRect не учитывает ряд отсупов).
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
|
(Offline)
|
|
13.07.2011, 10:33
|
#6
|
Злобный Админ
Регистрация: 04.09.2005
Сообщений: 5,926
Написано 3,415 полезных сообщений (для 9,330 пользователей)
|
Ответ: GetWindowRect
Деление на два нацело.
__________________
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
13.07.2011, 11:23
|
#7
|
Зануда с интернетом
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений (для 20,935 пользователей)
|
Ответ: GetWindowRect
Стал искать альтернативные пути.
Сперва хотел через
GetWindowInfo получить структуру WINDOWINFO, но оно чего-то заломалось, да и чрезмерно монструозно.
Поэтом применил другой костыль.
GetWindowPlacement и анализ поля rcNormalPosition структуры WINDOWPLACEMENT
int tx,ty;
HDWP windefer;
WINDOWPLACEMENT GCodeInfo;
int DeskTopXSize=GetSystemMetrics(SM_CXSCREEN);
int DeskTopYSize=GetSystemMetrics(SM_CYSCREEN);
GCodeInfo.length=sizeof(WINDOWPLACEMENT);
GetWindowPlacement(hSplashWnd, &GCodeInfo);
int width=GCodeInfo.rcNormalPosition.right-GCodeInfo.rcNormalPosition.left;
int height=GCodeInfo.rcNormalPosition.bottom-GCodeInfo.rcNormalPosition.top;
tx=(DeskTopXSize - width) >> 1;
ty=(DeskTopYSize - height) >> 1;
Можно аналогично запилить и центровку относительно родительского окна. В моём случае, достаточно по декстопу.
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
|
(Offline)
|
|
13.07.2011, 11:49
|
#8
|
Знающий
Регистрация: 18.02.2008
Сообщений: 276
Написано 121 полезных сообщений (для 299 пользователей)
|
Ответ: GetWindowRect
Сообщение от .Squid
Если нужно отцентрировать окно, то сначала получаешь его размеры (у тебя уже есть).
Затем получаешь размер декстопа:
int dx = GetSystemMetrics(SM_CXSCREEN);
int dy = GetSystemMetrics(SM_CYSCREEN);
Центрируешь:
int x = (dx - width) >> 1;
int y = (dy - height) >> 1;
SetWindowPos(rWnd, HWND_TOP, x, y, width, height, SWP_SHOWWINDOW);
|
Окно получается не совсем по центру, т.к. не учитывается размер рамки.
Я центрирую так:
/* (width, height - размеры окна) */
/* Get Desktop size */
tagRECT rect;
GetClientRect( GetDesktopWindow(), &rect );
/* Calc position and size of the new window */
rect.left = (rect.right - width) >> 1;
rect.right = rect.left + width;
rect.top = (rect.bottom - height) >> 1;
rect.bottom = rect.top + height;
/* Adjust window size */
AdjustWindowRect(&rect, GetWindowLong(_vpWindow, GWL_STYLE), false);
SetWindowPos(_vpWindow, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, 0);
Клиентская область получается ровно по центру.
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
13.07.2011, 11:53
|
#9
|
Зануда с интернетом
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений (для 20,935 пользователей)
|
Ответ: GetWindowRect
2 wolfhound512
Да, читал про эту функцию, но мне показалось* это ещё большим костылём (могу ошибаться).
http://www.firststeps.ru/mfc/winapi/r.php?73 :
Правда эта функция не учитывает, что меню может быть в два ряда, если окно маленькое. Так же она не учитывает стили WS_VSCROLL или WS_HSCROLL. Для этого нужно вызывать GetSystemMetrics().
|
Хотя вышеперечисленных свистелок моё окно не имеет (сплеш-скрин)
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
|
(Offline)
|
|
13.07.2011, 13:25
|
#10
|
Элита
Регистрация: 16.01.2010
Адрес: Новосибирск
Сообщений: 2,158
Написано 502 полезных сообщений (для 1,012 пользователей)
|
Ответ: GetWindowRect
Сообщение от Randomize
Что означает конструкция ">> 1"?
|
рандом,ты это не знал???смешение наверно каждый знает что такое,но не знает как пользоватся
научити меня нормально этим пользоваться,а то мне проще поделить на 10,чем смешение использовать
|
(Offline)
|
|
13.07.2011, 13:38
|
#11
|
Дэвелопер
Регистрация: 13.02.2010
Сообщений: 1,645
Написано 620 полезных сообщений (для 2,419 пользователей)
|
Ответ: GetWindowRect
смешение != смещение
|
(Offline)
|
|
13.07.2011, 13:44
|
#12
|
☭
Регистрация: 26.09.2006
Сообщений: 6,035
Написано 1,474 полезных сообщений (для 2,707 пользователей)
|
Ответ: GetWindowRect
на 10 нельзя
можно только на 8 или на 16
|
(Offline)
|
|
13.07.2011, 14:07
|
#13
|
Элита
Регистрация: 16.01.2010
Адрес: Новосибирск
Сообщений: 2,158
Написано 502 полезных сообщений (для 1,012 пользователей)
|
Ответ: GetWindowRect
на 10 нельзя
можно только на 8 или на 16
|
а...точняк,поБайтно же
|
(Offline)
|
|
13.07.2011, 14:34
|
#14
|
Зануда с интернетом
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений (для 20,935 пользователей)
|
Ответ: GetWindowRect
ПОБИТОВО!!
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
|
(Offline)
|
|
13.07.2011, 14:41
|
#15
|
Элита
Регистрация: 16.01.2010
Адрес: Новосибирск
Сообщений: 2,158
Написано 502 полезных сообщений (для 1,012 пользователей)
|
Ответ: GetWindowRect
Сообщение от impersonalis
ПОБИТОВО!!
|
зы,один байт=8 бит...невкурсе??
|
(Offline)
|
|
Ваши права в разделе
|
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 09:55.
|