Новичок
Профиль
Группа: Участник
Сообщений: 48
Регистрация: 20.2.2012
Репутация: нет Всего: нет
|
Потиху изучаю WinAPI, и в последствии возникло пару проблем, которые пока не получается решить: 1) у меня есть 7 кнопок, каждая из них отвечает за свои действия. Как обрабатывать ситуации, когда нужны координаты мышки запомнить, причем для эллипса, круга, прямоугольника, и пр, для их рисования это необходимо? 2) как ограничить область рисования, не затрагивая панель, с кнопками? 3) Почему на фрагменте, связанном с рисованием линии, ее как таковую не рисует? Хотя перо создано, цвет задан также? Код: | Код | #include <windows.h> #include "stdafx.h" #include "Lab_1.h" #include "FormElements.h" #define MAX_LOADSTRING 100
const int cnt = 7; // количество кнопок в программе FormElements Button[cnt]; // класс, связанный с кнопками и их событиями
HINSTANCE hInst; // текущий экземпляр TCHAR szTitle[MAX_LOADSTRING]; // текст строки заголовка TCHAR szWindowClass[MAX_LOADSTRING]; // имя класса главного окна
// Отправить объявления функций, включенных в этот модуль кода: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); BOOL DrawLine(HDC hdc, int x1, int y1, int x2, int y2);
// А-ля void main() int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine);
MSG msg; HACCEL hAccelTable;
// инициализация глобальных строк LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_LAB_1, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance);
// выполнить инициализацию приложения: if (!InitInstance (hInstance, nCmdShow)) {return FALSE;}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_LAB_1));
// цикл сообщений приложения while(GetMessage(&msg, NULL, 0, 0)) { //если GetMessage вернул ошибку --> выход if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } }
return (int) msg.wParam; }
ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; // объем памяти, выделяемый под структуру wcex.lpfnWndProc = WndProc; // адрес функции обработки сообщений wcex.cbClsExtra = 0; // дополнительные байты после класса wcex.cbWndExtra = 0; // дополнительные байты после экземпляра окна wcex.hInstance = hInstance; // экземпляр приложения wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_LAB_1)); // иконка приложения wcex.hCursor = LoadCursor(NULL, IDC_ARROW); // курсор в приложении (его вид) wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); // цвет фона wcex.lpszMenuName = MAKEINTRESOURCE(IDC_LAB_1); // "имя" меню wcex.lpszClassName = szWindowClass; // имя класса окна wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); // уменьшенная иконка приложения return RegisterClassEx(&wcex); }
// Инициализация/создание окна, с рядом указанных параметров BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd,hPanel,hBtn[cnt],hDCWnd; hInst = hInstance; // cохранить дескриптор экземпляра в глобальной переменной
// создание главной "формы" программы DWORD WndStyle = WS_OVERLAPPED|WS_CAPTION|WS_MINIMIZEBOX|WS_SYSMENU; // есть заголовок, ограничение размера формы, блок кнопки "на весь экран" hWnd = CreateWindow(szWindowClass, L"Лабораторная №1", WndStyle, CW_USEDEFAULT, 0, 1024, 720, NULL, NULL, hInstance, NULL);
// создание панели DWORD dwExStyle = WS_EX_CLIENTEDGE|WS_EX_DLGMODALFRAME; // бордюр + "объем" панели DWORD dwStyle = WS_CHILD|WS_VISIBLE|SS_CENTER|SS_CENTERIMAGE|SS_SUNKEN; // дочерний, видимый, текст по центру объекта hPanel = CreateWindowEx(dwExStyle, L"STATIC", L"", dwStyle, 0, 0, 133, 672, hWnd, NULL, hInstance, NULL);
// формирование кнопок // 1. создадим для меток на кнопках двумерный массив строк, // содержащих надписи для кнопок int IDPar=10000; char **BtnTitles = new char *[7]; BtnTitles[0] = new char [5]; BtnTitles[0] = "Линия"; BtnTitles[1] = new char [13]; BtnTitles[1] = "Прямоугольник"; BtnTitles[2] = new char [11]; BtnTitles[2] = "Треугольник"; BtnTitles[3] = new char [4]; BtnTitles[3] = "Круг"; BtnTitles[4] = new char [5]; BtnTitles[4] = "Кисть"; BtnTitles[5] = new char [6]; BtnTitles[5] = "Ластик"; BtnTitles[6] = new char [4]; BtnTitles[6] = "Цвет"; // 2. теперь проинициализируем кнопки, и дадим им надписи и номера действий, с помощью класса for(int i=0; i<cnt; i++) { // задаем номер операции для кнопки, через метод, определенный в классе int OpNumber=i; Button[i].SetAction(OpNumber); // задаем title кнопки, указанного в классе Button[i].SetTitle(BtnTitles[i]); char *title=Button[i].GetTitle(); // переведем текст из char* в LPCWSTR, чтобы текст был виден корректно, а не виде иероглифов WCHAR str[15]; MultiByteToWideChar(0,0,title,15,str,15); //MultiByteToWideChar(0,0,BtnTitles[i],15,str,15); LPCWSTR corrected_title = str; // создаем кнопку hBtn[i] = CreateWindow(L"Button",(LPCWSTR)corrected_title,WS_TABSTOP|WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON, 10, 10+35*i, 115, 30, hWnd, (HMENU)IDPar, hInstance, NULL); IDPar++; }
if (!hWnd) {return FALSE;} ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; }
// Обработка сообщений, принятых от функции _tWinMain(...) LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc;
ps.rcPaint.bottom=49; ps.rcPaint.left=134; // каждую итерацию цикла проверяется очередь сообщений приложения. // И если в очереди сообщений есть сообщение, то оно вытаскивается из очереди. switch(message) { // разбор команды case WM_COMMAND: // реакция на нажатие одной из кнопок switch(LOWORD(wParam)) { //рисование линии case 10000: int cntPT=0; POINT begin,end; HDC hDC = ::GetDC(hWnd); HPEN hPen = CreatePen(PS_SOLID, 3, RGB(128, 128, 0)); while(WM_LBUTTONDOWN && cnt!=2) { switch(cnt) { case 0: begin.x = LOWORD(lParam); //x begin.y = HIWORD(lParam); //y break; case 1: end.x = LOWORD(lParam); //x end.y = HIWORD(lParam); //y break; } } DrawLine(hDC,begin.x,begin.y,end.x,end.y); InvalidateRect(hWnd,NULL,1); ::ReleaseDC(hWnd,hDC); break; /* case 10001: break; case 10002: break; case 10003: break; case 10004: break; case 10005: break; case 10006: break; */ } // получаем параметры wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // Выбор в меню: switch(wmId) { // нажали "Справка" case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; // нажали "Сохранить" // нажали "Выход" case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } break; // отображение формы case WM_PAINT: hdc = BeginPaint(hWnd, &ps); EndPaint(hWnd, &ps); break; // закрытие формы case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
// Обработчик сообщений для окна "О программе". INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); // проверяем очередь сообщений switch (message) { // если вызвано окно через меню, то его "отрисуем" case WM_INITDIALOG: return (INT_PTR)TRUE; // если же, нажат ESC или кнопка "ОК", то закрываем окно case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; }
// рисование линии BOOL DrawLine(HDC hdc, int x1, int y1, int x2, int y2) { POINT pt; MoveToEx(hdc, x1, y1, &pt); return LineTo(hdc, x2, y2); }
|
Это сообщение отредактировал(а) Relrin - 5.9.2012, 16:01
|