Форум программистов
 
Контакты: о проблемах с регистрацией, почтой и по другим вопросам пишите сюда - alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите активизацию e-mail.

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

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

Здесь нужно купить рекламу за 20 тыс руб в месяц! ) пишите сюда - alarforum@yandex.ru
Без учёта ботов - 20000 человек в день, 350000 в месяц.

Ответ
 
Опции темы
Старый 09.09.2019, 21:06   #1
LomionDK
Пользователь
 
Регистрация: 24.02.2019
Сообщений: 33
По умолчанию Дочернее окно перемещается в тот угол рабочей области, где нажали левую клавишу мыши

Есть такое задание: В центре рабочей области окна отображено дочернее окно с вертикальными и
горизонтальными полосами прокрутки размером в четверть этой области. Дочернее
окно перемещается в тот угол рабочей области, где нажали левую клавишу мыши.
Есть программа, в которой по клику на дочернее окно, оно перемещается по часовой стрелки. Помогите изменить так, чтобы перемещалось к тому углу, по которому кликнул. Т.е. к той части, к которой ближе был клик.
Код:
#include <windows.h>
#include <tchar.h>

LPCTSTR lpClassName = _T("MainClass");
LPCTSTR lpChildClassName = _T("ChildClass");
HINSTANCE g_hInstance = NULL;
HWND hwndMainForm = NULL;
HWND hwndChildForm = NULL;
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK ChildWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

void
InitMainClass()
{
	WNDCLASS wc;

	// регистрируем класс главного окна
	ZeroMemory(&wc, sizeof(WNDCLASS));
	wc.hInstance = g_hInstance;
	wc.lpszClassName = lpClassName;
	wc.lpfnWndProc = WindowProc;
	wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
	wc.hIcon = LoadIcon((HINSTANCE)NULL, IDI_APPLICATION);
	wc.hCursor = LoadCursor((HINSTANCE)NULL, IDC_ARROW);
	RegisterClass(&wc);

	// регистрируем класс дочернего окна
	ZeroMemory(&wc, sizeof(WNDCLASS));
	wc.hInstance = g_hInstance;
	wc.lpszClassName = lpChildClassName;
	wc.lpfnWndProc = ChildWindowProc;
	wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
	wc.hIcon = LoadIcon((HINSTANCE)NULL, IDI_APPLICATION);
	wc.hCursor = LoadCursor((HINSTANCE)NULL, IDC_ARROW);
	RegisterClass(&wc);
}

/*******************************************************************************
 * Description: Создаем главное окно и дочернее окно
 ******************************************************************************/
int
CreateMainForm()
{
	DWORD dwExStyle = 0;
	DWORD dwStyle = WS_OVERLAPPEDWINDOW;
	// создаем главное окно
	hwndMainForm = CreateWindowEx(dwExStyle, lpClassName, _T("Main window"), dwStyle,CW_USEDEFAULT, CW_USEDEFAULT, 600, 600, (HWND)NULL, (HMENU)NULL, g_hInstance, (LPVOID)NULL);
	if (hwndMainForm == NULL) return 1001;
	ShowWindow(hwndMainForm, SW_NORMAL);
	UpdateWindow(hwndMainForm);

	// получаем координаты клиентской области главного окна
	// для вычисления размеров дочернего окна
	RECT rc;
	GetClientRect(hwndMainForm, &rc);

	// создаем дочернее окно размером в 1/4 главного окна
	dwExStyle = WS_EX_TOOLWINDOW;
	dwStyle = WS_CHILDWINDOW | WS_OVERLAPPED | WS_CAPTION;
	hwndChildForm = CreateWindowEx(dwExStyle, lpChildClassName,_T("Дочернее"), dwStyle| WS_HSCROLL | WS_VSCROLL, 600/4, 600/4, rc.right / 2, rc.bottom / 2, hwndMainForm, (HMENU)NULL, g_hInstance, (LPVOID)NULL);
	if (hwndChildForm == NULL) return 1002;
	ShowWindow(hwndChildForm, SW_NORMAL);
	UpdateWindow(hwndChildForm);

	return 0;
}

/*******************************************************************************
 * Description: Обработка сообщений главного окна
 ******************************************************************************/
LRESULT CALLBACK
WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
	case WM_CLOSE: // Закрытие основного окна
		SendMessage(hwndChildForm, WM_CLOSE, 0, 0); // уничтожаем дочернее окно
		DestroyWindow(hWnd); // уничтожаем главное
		UnregisterClass(lpClassName, g_hInstance); // разрегистрируем класс главного окна
		PostQuitMessage(0); // прерываем цикл выборки сообщений
		break;
	} // switch(uMsg)

	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

/*******************************************************************************
 * Description: Обработка сообщений главного окна
 ******************************************************************************/
LRESULT CALLBACK
ChildWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	static unsigned short index = 1;// сюда
	switch (uMsg)
	{
	case WM_LBUTTONDOWN:
		//отсюда переставить вверх
// переменная для определения в каком углу сейчас находится окно
		RECT rcOwner, rcChild, rcTemp;
		GetClientRect(hwndMainForm, &rcOwner); // получаем координаты клиентской области главного окна
		GetWindowRect(hWnd, &rcChild); // получаем координаты дочернего окна
		CopyRect(&rcTemp, &rcOwner); // копируем координаты главного окна в буфер
		OffsetRect(&rcChild, -rcChild.left, -rcChild.top); // "перемещаем" для простоты дочернее окно в координаты 0,0
		OffsetRect(&rcTemp, -rcTemp.left, -rcTemp.top); // "перемещаем" для простоты главное окно в координаты 0,0
		switch (index)
		{
		case 1:
			// вычисляем новые координаты дочернего окна
			OffsetRect(&rcTemp, -rcChild.right, -rcChild.bottom);
			rcTemp.bottom = 0;
			index++; // "увеличиваем" угол
			break;
		case 2:
			// вычисляем новые координаты дочернего окна
			OffsetRect(&rcTemp, -rcChild.right, -rcChild.bottom);
			index++;
			break;
		case 3:
			// вычисляем новые координаты дочернего окна
			OffsetRect(&rcTemp, -rcChild.right, -rcChild.bottom);
			rcTemp.right = 0;
			index++;
			break;
		case 4:
			// вычисляем новые координаты дочернего окна
			OffsetRect(&rcTemp, -rcChild.right, -rcChild.bottom);
			rcTemp.right = 0;
			rcTemp.bottom = 0;
			index = 1; // следующий угол - левый верхний
			break;
		} // switch(index)

		// действительно перемещаем дочернее окно без изменения его размера
		SetWindowPos(hwndChildForm, HWND_TOP, rcOwner.left + rcTemp.right, rcOwner.top + rcTemp.bottom, 0, 0, SWP_NOSIZE);
		break;
	case WM_CLOSE: // Закрытие дочернего окна
		DestroyWindow(hwndChildForm);
		UnregisterClass(lpChildClassName, g_hInstance);
		break;
	} // switch(uMsg)

	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

/*******************************************************************************
 * Description: Основная функция приложения (стартовая точка)
 ******************************************************************************/
int WINAPI
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	// копируем указатель приложения в глобальную переменную
	g_hInstance = hInstance;

	// Регистрируем классы, создаем окна
	InitMainClass();
	CreateMainForm();

	// Запускаем цикл обработки сообщений
	MSG Msg;
	while (GetMessage(&Msg, (HWND)NULL, 0, 0))
	{
		TranslateMessage(&Msg);
		DispatchMessage(&Msg);
	} // while(GetMessage(&Msg, (HWND)NULL, 0, 0))

	return Msg.wParam;
}
LomionDK вне форума Ответить с цитированием
Ответ
Опции темы


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Дочернее окно HTTqp Общие вопросы Delphi 0 10.10.2015 22:46
Дочернее окно (MFC / C++) feelmyeyes Помощь студентам 0 27.11.2013 21:28
Дочернее и родительское окно. Sonny01 Помощь студентам 2 30.10.2011 18:11
[?] Послать клавишу в чужое окно, не выводя окно на передний план. Moriarty Win Api 4 21.02.2011 06:11
Дочернее окно StayS Общие вопросы Delphi 2 24.09.2008 20:22