Здравствуйте, уважаемые участники форума. Получил вот такое задание, но возникли проблемы... Программа Win32 для рисования на экране прямых линий. Начало и конец линии задаются двумя последовательными нажатиями на левую кнопку мыши в основном окне программы. Нажатие на правую очищает экран. Также должен автоматически очищаться через время t после рисования последней линии. Добиться сохранения рисунка при помощи memory bitmaps после перекрытия окна лругими окнами. При выборе свойства линии, программа должна вывести диал. окно. в checkbox выбираем тип (штриховая или сплошная). А radio buttons для цветов. Таймаут - тут задается t. Выход - запрашивает о выходе, и при утвердительном ответе обновить в ini-файле все параметры (тип линии, время таймаута), после этого завершить работу. При повторном запуске, программа загрузит сохраненные параметры из ini-файла. Проблема в том, что программа виснет при выборе дочернего элемента в гл. меню. Кроме того она не рисует штриховые линии . Я пробовал менят время задержки, последовательно комментировать те или иные функции и пр., с отладчиком. Ничего. Мне кажется, что дело в WM_PAINT. Иногда получалось по-отдельности включать нужные функции, но все вместе - никогда не работало. Сам над этим уже два месяца голову ломаю, ничего не могу сделать. Если совсем никак, то можете удалить пост или не смотреть вообще. С меня много плюсиков, если получится! Проект (включая resource.h и пр.) для MSVS 2005 выложил тут в *.rar А вот то нечто, что мне удалось написать: Code: #include <windows.h> #include <stdio.h> #include "resource.h" #define TIMER_ID 1 HINSTANCE hhh; int dedit=5; int colornumber=1; bool linestyle=false; bool startline=true; bool t=false; int x,y,x0,y0; HPEN pen; LRESULT CALLBACK WindowFunc(HWND,UINT,WPARAM,LPARAM); //------------------------------------------------------------------- // WinMain //------------------------------------------------------------------- int WINAPI WinMain (HINSTANCE hThisInst, HINSTANCE hPrevInst, LPSTR lpszArgs, int nWinMode) { char szWinName[] = "класс окна"; MSG msg; HWND hwnd; WNDCLASS wcl; hhh=hThisInst; // класс окна wcl.hInstance = hThisInst; //идентификатор приложения wcl.lpszClassName = szWinName; //имя класса окна wcl.lpfnWndProc = WindowFunc; //функция окна wcl.style = 0; // стиль по умолчанию wcl.hIcon = LoadIcon(NULL,IDI_APPLICATION); //стандартная иконка wcl.hCursor = LoadCursor(NULL,IDC_ARROW); //стандартный курсор мыши wcl.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1); //без меню wcl.cbClsExtra = 0; wcl.cbWndExtra = 0; wcl.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH); // Цвет фона окна if (!RegisterClass (&wcl)) return 0; // CreateWindow hwnd = CreateWindow(szWinName,"Мое первое оконо", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, // горизонтальное положение окна CW_USEDEFAULT, // вертикальное положение окна CW_USEDEFAULT, // ширина окна CW_USEDEFAULT, // высота окна HWND_DESKTOP, NULL, hThisInst, NULL); // Показать окно и нарисовать содержимое ShowWindow(hwnd,nWinMode); // Цикл обработки сообщений while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg); DispatchMessage (&msg); } return msg.wParam; } //------------------------------------------------------------------- //диалоговое окно BOOL CALLBACK DialogProcTime(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { char str[10]; switch (uMsg) { case WM_INITDIALOG: sprintf(str,"%d",dedit); SetDlgItemText(hDlg,IDC_EDIT1,str); return TRUE; break; case WM_COMMAND: switch(LOWORD(wParam)) { case IDOK: GetDlgItemText(hDlg,IDC_EDIT1,str,10); dedit = atoi(str); EndDialog(hDlg,TRUE); return TRUE; break; case IDCANCEL: EndDialog(hDlg,TRUE); return TRUE; break; } break; } return FALSE; } //диалоговое окно BOOL CALLBACK DialogProcSvoistva(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { /* switch (uMsg) { case (WM_INITDIALOG): CheckRadioButton(hDlg, IDC_RADIO1, IDC_RADIO5, IDC_RADIO1+colornumber-1); if (linestyle) CheckDlgButton(hDlg, IDC_CHECK1, BST_CHECKED); else CheckDlgButton(hDlg, IDC_CHECK1, BST_UNCHECKED); return TRUE; break; case WM_COMMAND: switch(LOWORD(wParam)) { case IDOK: if (IsDlgButtonChecked(hDlg, IDC_RADIO1)) colornumber=1; if (IsDlgButtonChecked(hDlg, IDC_RADIO2)) colornumber=2; if (IsDlgButtonChecked(hDlg, IDC_RADIO3)) colornumber=3; if (IsDlgButtonChecked(hDlg, IDC_RADIO4)) colornumber=4; if (IsDlgButtonChecked(hDlg, IDC_RADIO5)) colornumber=5; if (IsDlgButtonChecked(hDlg, IDC_CHECK1)) linestyle=true; else linestyle=false; EndDialog(hDlg,TRUE); return TRUE; break; case IDCANCEL: EndDialog(hDlg,TRUE); return TRUE; break; } break; } */ return FALSE; } // Функция - обработчик сообщений окна //------------------------------------------------------------------- LRESULT CALLBACK WindowFunc(HWND hwnd,UINT message, WPARAM wParam,LPARAM lParam) { PAINTSTRUCT ps; HDC dc; HPEN blackpen,whitepen,redpen,greenpen,bluepen; switch (message) { case WM_DESTROY: PostQuitMessage(0); break; case WM_COMMAND: switch(LOWORD(wParam)) { case ID_EXIT: if (MessageBox(hwnd,"Действительно ли вы хотите выйти?","",MB_OKCANCEL)==IDOK) { PostQuitMessage(0); } break; case ID_TIMEOUT: DialogBox(hhh,MAKEINTRESOURCE(IDD_DIALOG1),hwnd,DialogProcTime); break; case ID_SVOISTVA: DialogBox(hhh,MAKEINTRESOURCE(IDD_DIALOG2),hwnd,DialogProcSvoistva); break; } break; case WM_PAINT: if (t) { dc=BeginPaint(hwnd, &ps); if (startline) { x0=x; y0=y; startline=false; } else { blackpen=CreatePen(PS_SOLID,2,RGB(0,0,0)); whitepen=CreatePen(PS_SOLID,2,RGB(255,255,255)); redpen=CreatePen(PS_SOLID,2,RGB(255,0,0)); greenpen=CreatePen(PS_SOLID,2,RGB(0,255,0)); bluepen=CreatePen(PS_SOLID,2,RGB(0,0,255)); if (colornumber==1) SelectObject(dc,blackpen); if (colornumber==2) SelectObject(dc,whitepen); if (colornumber==3) SelectObject(dc,redpen); if (colornumber==4) SelectObject(dc,greenpen); if (colornumber==5) SelectObject(dc,bluepen); MoveToEx(dc, x0, y0, NULL); LineTo(dc, x, y); startline=true; SetTimer(hwnd,TIMER_ID,1000*dedit,NULL); } EndPaint(hwnd, &ps); } break; case WM_LBUTTONDOWN : x=LOWORD(lParam); y=HIWORD(lParam); t=true; InvalidateRect(hwnd,0,FALSE); UpdateWindow(hwnd); break; case WM_RBUTTONDOWN : t=false; InvalidateRect(hwnd,0,TRUE); UpdateWindow(hwnd); startline=true; break; case WM_TIMER: KillTimer(hwnd,TIMER_ID); t=false; InvalidateRect(hwnd,0,TRUE); UpdateWindow(hwnd); break; default: return DefWindowProc (hwnd, message, wParam, lParam); } return 0; } Спасибо заранее, если посмотрите, так как в C++ я совсем чайник.
Сейчас времени уже нету, позже посмотрю внимательнее. Она кстати у тебя не виснет, просто создаёт диалог но фокус на него не передаёт(без нажатия alt), похоже что фокус остаётся у меню бара, почему я так и не понял... 1) Тело функции обработки диалога зря закоментил. 2) return TRUE не везде возвращяешь.
У тебя с проектом что-то не так, я так и не нашел что, создай новый проект, НЕ КОПИРУЙ диалоговые окна, пункты меню и даже их элементы, не копируй свои функции, делай точно как в заготовке проекта и должно всё работать Я пробовал создать новый проект, скопировать туда твой диалог и функцию колбэка и получилась та-же чушь, так что НЕ КОПИРУЙ. Насчёт пунктиров, так функция CreatePen не умеет рисовать пунктиры шире одного пикселя, вроде-бы ExtCreatePen умеет или используй "GDI Plus"
Респект! Вобщем, с текстом можно так, насколько я понял: Code: void CTextWnd::OnPaint() { CPaintDC dc(this); dc.SetTextColor(clrText); dc.SetBkColor(::GetSysColor(COLOR_WINDOW)); CRect rect; GetClientRect(rect); dc.DrawText(_TEXT("Обработка WM_PAINT"), -1, rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER); } Вот. Что касается нетекстовых элементов, то, видимо нужно использовать memory bitmaps (как-то ). То есть можно и без этого, но если графики много, всё же оно целесообразно. Странно, вроде если брать CreatePen, то можно пользоваться либо PS_SOLID, либо PS_DASH. Или я тут что-то напутал с CreatePen и ExtCreatePen. P.S. Половину дня убил на поиски ресурсов по теме. Нашёл вот эту статью -- вполне информативно! Ладно, я ещё покопаюсь. Надеюсь, всё же озарение будет -- тогда обязательно отпишусь!