Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 01.12.2011, 17:25   #1
RAZOR1703
Пользователь
 
Регистрация: 15.12.2010
Сообщений: 74
По умолчанию Отслеживание изменения положения и размеров окна

Добрый день.
Допустим, у меня есть каркас оконного приложения:
Код:
#define _WIN32_WINNT 0x501
#include <windows.h>
#define MENUITEM_0 101
#define MENUITEM_1 102
#define MENUITEM_2 103
#define MENUITEM_3 104
#define MENUITEM_4 105
#define MENUITEM_5 104
#define MENUITEM_6 105
#define MIIM_FTYPE 106
#define MIIM_STRING 107

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
 HMENU hMenu;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
 static char szAppName[] = "My Window";
 HWND hwnd;
 MSG msg;
 WNDCLASSEX wndclass;
 int x = CW_USEDEFAULT,
	 y = CW_USEDEFAULT,
	sx = 325,
	sy = 200;

 wndclass.cbSize = sizeof(wndclass);

 wndclass.style = CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS;
 wndclass.lpfnWndProc = WndProc;
 wndclass.cbClsExtra = 0;
 wndclass.cbWndExtra = 0;
 wndclass.hInstance = hInstance;
 wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
 wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
 wndclass.hbrBackground = (HBRUSH) GetStockObject(COLOR_BACKGROUND);
 wndclass.lpszMenuName = NULL;
 wndclass.lpszClassName = szAppName;
 wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
 RegisterClassEx (&wndclass);

 hwnd = CreateWindow
  (szAppName,
  "My Window App",
  WS_OVERLAPPEDWINDOW,
  x,
  y,
  sx,
  sy,
  NULL,
  hMenu,
  hInstance,
  NULL);
 ShowWindow(hwnd,iCmdShow);
 UpdateWindow (hwnd);
 while (GetMessage(&msg, NULL, 0, 0))
 {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
 }

 return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
 HDC hdc;
 PAINTSTRUCT ps;
 RECT rect;
 LPCSTR MyStr = "First Window";
 static int currenttime=0, lastclick=0;
while (1)
{
 switch (iMsg)
 {
   
 case WM_PAINT: 
  hdc = BeginPaint (hwnd, &ps);
  DrawTextA (hdc, MyStr, -1, &rect, DT_SINGLELINE|DT_CENTER|DT_VCENTER);
  EndPaint (hwnd, &ps);
  return 0;
  break;

 case WM_DESTROY:
   PostQuitMessage (0);

  }
}
 return DefWindowProc (hwnd, iMsg, wParam, lParam);
}
Каким образом я могу на лету отслеживать размеры и положение окна?
RAZOR1703 вне форума Ответить с цитированием
Старый 01.12.2011, 20:03   #2
*PB*
Форумчанин
 
Регистрация: 11.08.2009
Сообщений: 558
По умолчанию

Цитата:
Сообщение от RAZOR1703 Посмотреть сообщение
Каким образом я могу на лету отслеживать размеры и положение окна?
События WM_SIZE и WM_MOVE вам в помощь.
*PB* вне форума Ответить с цитированием
Старый 01.12.2011, 21:21   #3
RAZOR1703
Пользователь
 
Регистрация: 15.12.2010
Сообщений: 74
По умолчанию

*PB*
Спасибо, уже допёр. Теперь интересная вещь появилась: при старте программы я беру значения из реестра, а в случае изменения пишу их туда. И все, казалось бы, хорошо, НО, при каждом последующем запуске мое окошко становится меньше, и меньше, и меньше. Причем уменьшается и сверху, и снизу.
Не пойму никак.
Код:
#define _WIN32_WINNT 0x501
#include <windows.h>
#define MENUITEM_0 101
#define MENUITEM_1 102
#define MENUITEM_2 103
#define MENUITEM_3 104
#define MENUITEM_4 105
#define MENUITEM_5 104
#define MENUITEM_6 105
#define MIIM_FTYPE 106
#define MIIM_STRING 107
static HKEY hk;
static DWORD dwDsp;
static DWORD PosX, PosY, SizeX, SizeY;
static DWORD cData = sizeof (PosX);

HMENU hMenu;
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
 static char szAppName[] = "My Window";
 HWND hwnd;
 MSG msg;
 WNDCLASSEX wndclass;
 RegCreateKeyEx (HKEY_CURRENT_USER, "Software\\My LabSPO", 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hk, &dwDsp);
 if (dwDsp == REG_OPENED_EXISTING_KEY)
 {
	RegQueryValueEx (hk, "Window size X", 0, NULL,(LPBYTE)&SizeX, &cData);
	RegQueryValueEx (hk, "Window size Y", 0, NULL,(LPBYTE)&SizeY, &cData);
	RegQueryValueEx (hk, "Window position X", 0, NULL,(LPBYTE)&PosX, &cData);
	RegQueryValueEx (hk, "Window position Y", 0, NULL,(LPBYTE)&PosY, &cData);	 
 }

 wndclass.cbSize = sizeof(wndclass);

 wndclass.style = CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS;
 wndclass.lpfnWndProc = WndProc;
 wndclass.cbClsExtra = 0;
 wndclass.cbWndExtra = 0;
 wndclass.hInstance = hInstance;
 wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
 wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
 wndclass.hbrBackground = (HBRUSH) GetStockObject(COLOR_BACKGROUND);
 wndclass.lpszMenuName = NULL;
 wndclass.lpszClassName = szAppName;
 wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
 RegisterClassEx (&wndclass);

 hwnd = CreateWindow
  (szAppName,
  "My Window App",
  WS_OVERLAPPEDWINDOW,
  (int)PosX,
  (int)PosY,
  (int)SizeX,
  (int)SizeY,
  NULL,
  hMenu,
  hInstance,
  NULL);
 ShowWindow(hwnd,iCmdShow);
 UpdateWindow (hwnd);
 RegCloseKey(hk);
 while (GetMessage(&msg, NULL, 0, 0))
 {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
 }

 return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
 HDC hdc;
 PAINTSTRUCT ps;
 RECT rect;
 LPCSTR MyStr = "First Window";
 HMENU hMenu1;
 HMENU hMenu2;
 HMENU hMenu3;
 HMENU hMenu4;
 static int currenttime=0, lastclick=0;
  RegCreateKeyEx (HKEY_CURRENT_USER, "Software\\My LabSPO", 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hk, &dwDsp);
 switch (iMsg)
 {
 case WM_LBUTTONDOWN:
  hMenu = CreateMenu();
  hMenu1 = CreatePopupMenu();
  hMenu2 = CreatePopupMenu();
  hMenu3 = CreatePopupMenu();
  hMenu4 = CreatePopupMenu();
  InsertMenu(hMenu, 1, MF_BYPOSITION|MFT_STRING|MF_POPUP, (UINT)hMenu1, "Menu");
  InsertMenu(hMenu1, 2, MF_BYPOSITION|MFT_STRING|MF_POPUP, (UINT)hMenu2, "First");
  InsertMenu(hMenu2, 3, MF_BYPOSITION|MFT_STRING, MENUITEM_1, "First-first");
  InsertMenu(hMenu2, 4, MF_BYPOSITION|MFT_STRING, MENUITEM_2, "First-second");
  InsertMenu(hMenu1, 5, MF_BYPOSITION|MFT_STRING|MF_POPUP, (UINT)hMenu3, "Second");
  InsertMenu(hMenu3, 6, MF_BYPOSITION|MFT_STRING, MENUITEM_3, "Second-first");
  InsertMenu(hMenu3, 7, MF_BYPOSITION|MFT_STRING, MENUITEM_4, "Second-second");
  InsertMenu(hMenu1, 8, MF_BYPOSITION|MFT_STRING|MF_POPUP, (UINT)hMenu4, "Third");
  InsertMenu(hMenu4, 9, MF_BYPOSITION|MFT_STRING, MENUITEM_5, "Third-first");
  InsertMenu(hMenu4, 10, MF_BYPOSITION|MFT_STRING, MENUITEM_6, "Third-second");
  DrawMenuBar (hwnd);
  SetMenu(hwnd,hMenu);
  return 0;
  break;
 
 case WM_LBUTTONDBLCLK:
  MessageBox(NULL, "You've doubleclicked MB! Good job out there.","You're genius! Made your momma proud", 0);
  return 0;
  break;
  
 case WM_PAINT: 
  hdc = BeginPaint (hwnd, &ps);
  DrawTextA (hdc, MyStr, -1, &rect, DT_SINGLELINE|DT_CENTER|DT_VCENTER);
  EndPaint (hwnd, &ps);
  return 0;
  break;
  
 case WM_CONTEXTMENU:
	 TrackPopupMenu(hMenu, TPM_RIGHTBUTTON|TPM_TOPALIGN|TPM_LEFTALIGN,
		 LOWORD(lParam), HIWORD(lParam),0,hwnd,NULL);
	 break;

 case WM_RBUTTONUP:
  DestroyMenu(hMenu);
  PostQuitMessage (0);
  break;
 
 case WM_MOVE:
	 PosX = (DWORD)LOWORD(lParam);
	 PosY = (DWORD)HIWORD(lParam);
	 break;

 case WM_SIZE:
	 SizeX = (DWORD)LOWORD(lParam);
	 SizeY = (DWORD)HIWORD(lParam);
	 break;

 case WM_DESTROY:
	RegSetValueEx (hk, "Window position X", 0, REG_DWORD, (LPBYTE)&PosX, sizeof(PosX));
	RegSetValueEx (hk, "Window position Y", 0, REG_DWORD, (LPBYTE)&PosY, sizeof(PosY));
	 RegSetValueEx (hk, "Window size X", 0, REG_DWORD, (LPBYTE)&SizeX, sizeof(SizeX));
	 RegSetValueEx (hk, "Window size Y", 0, REG_DWORD, (LPBYTE)&SizeY, sizeof(SizeY));
	DestroyMenu(hMenu);
	RegCloseKey (hk);
	PostQuitMessage(0);
  }

 return DefWindowProc (hwnd, iMsg, wParam, lParam);
}
RAZOR1703 вне форума Ответить с цитированием
Старый 01.12.2011, 21:37   #4
RAZOR1703
Пользователь
 
Регистрация: 15.12.2010
Сообщений: 74
По умолчанию

Причем, что я заметил. Если запускать несколько окон, то вот что получается:

То есть, уменьшение идет как раз на размер рамки. С чем это связано и почему он пишет это сразу в реестр, ведь у меня изменение реестра идет только по закрытию программы?
RAZOR1703 вне форума Ответить с цитированием
Старый 01.12.2011, 23:24   #5
Exception
Пользователь
 
Регистрация: 31.12.2007
Сообщений: 37
По умолчанию

Да это приходит размер клиентской части. В WM_DESTROY вызывай GetWindowRect. Если не ошибаюсь конечно...
Exception вне форума Ответить с цитированием
Старый 01.12.2011, 23:36   #6
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

вы справку читали про WM_SIZE?
Цитата:
lParam

The low-order word of lParam specifies the new width of the client area.

The high-order word of lParam specifies the new height of the client area.
вот и выходит у вас.
вам нужно руками получать размер всего окна, а не только его клиентской части(без рамки например)
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 01.12.2011, 23:42   #7
RAZOR1703
Пользователь
 
Регистрация: 15.12.2010
Сообщений: 74
По умолчанию

Не совсем понимаю, как мне ее использовать. Можно чуть подробнее? Что мне делать после того, как получил структуру с координатами?
Цитата:
вам нужно руками получать размер всего окна, а не только его клиентской части(без рамки например)
Можно узнать, каким образом?

Последний раз редактировалось RAZOR1703; 01.12.2011 в 23:46.
RAZOR1703 вне форума Ответить с цитированием
Старый 02.12.2011, 00:55   #8
*PB*
Форумчанин
 
Регистрация: 11.08.2009
Сообщений: 558
По умолчанию

Используйте функции GetWindowPlacement() и SetWindowPlacement().
*PB* вне форума Ответить с цитированием
Старый 02.12.2011, 01:39   #9
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

GetWindowRect, но в чем проблема по координатам выяснить ширину/высоту?
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 03.12.2011, 16:43   #10
RAZOR1703
Пользователь
 
Регистрация: 15.12.2010
Сообщений: 74
По умолчанию

Спасибо, всё получилось.
RAZOR1703 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как уловить начало изменения размеров формы. novichok1 Общие вопросы Delphi 13 09.02.2011 17:37
Изменение размеров окна Liones Общие вопросы Delphi 4 15.10.2010 09:01
Определение размеров компонента и положения по хендлу Marsel737 Общие вопросы Delphi 10 03.05.2010 00:53
Изменение размеров окна Light Alloy Общие вопросы Delphi 2 06.10.2009 07:21
Существует ли внешний компонент типа TImage, с возможностью изменения размера и положения в RunTime? Лукманов Александр Компоненты Delphi 8 28.04.2009 10:56