ANTICHAT — форум по информационной безопасности, OSINT и технологиям
ANTICHAT — русскоязычное сообщество по безопасности, OSINT и программированию.
Форум ранее работал на доменах antichat.ru, antichat.com и antichat.club,
и теперь снова доступен на новом адресе —
forum.antichat.xyz.
Форум восстановлен и продолжает развитие: доступны архивные темы, добавляются новые обсуждения и материалы.
⚠️ Старые аккаунты восстановить невозможно — необходимо зарегистрироваться заново.
 |
C++ граф. задача нужна помощь |

21.05.2007, 00:37
|
|
Новичок
Регистрация: 04.06.2006
Сообщений: 29
Провел на форуме: 133649
Репутация:
6
|
|
C++ граф. задача нужна помощь
Здравствуйте, уважаемые участники форума. Получил вот такое задание, но возникли проблемы...
Программа Win32 для рисования на экране прямых линий. Начало и конец линии задаются двумя последовательными нажатиями на левую кнопку мыши в основном окне программы. Нажатие на правую очищает экран. Также должен автоматически очищаться через время t после рисования последней линии. Добиться сохранения рисунка при помощи memory bitmaps после перекрытия окна лругими окнами.
При выборе свойства линии, программа должна вывести диал. окно. в checkbox выбираем тип (штриховая или сплошная). А radio buttons для цветов.
Таймаут - тут задается t.
Выход - запрашивает о выходе, и при утвердительном ответе обновить в ini-файле все параметры (тип линии, время таймаута), после этого завершить работу. При повторном запуске, программа загрузит сохраненные параметры из ini-файла.
Проблема в том, что программа виснет при выборе дочернего элемента в гл. меню. Кроме того она не рисует штриховые линии  . Я пробовал менят время задержки, последовательно комментировать те или иные функции и пр., с отладчиком. Ничего. Мне кажется, что дело в WM_PAINT. Иногда получалось по-отдельности включать нужные функции, но все вместе - никогда не работало.  Сам над этим уже два месяца голову ломаю, ничего не могу сделать.
Если совсем никак, то можете удалить пост или не смотреть вообще.
С меня много плюсиков, если получится!
Проект (включая resource.h и пр.) для MSVS 2005 выложил тут в *.rar
А вот то нечто, что мне удалось написать:
Код:
#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++ я совсем чайник.
Последний раз редактировалось Visor; 22.05.2007 в 20:07..
|
|
|

21.05.2007, 07:14
|
|
Pagan Heart
Регистрация: 12.08.2004
Сообщений: 3,791
Провел на форуме: 6490435
Репутация:
2290
|
|
Тебе обязательно на апях?
|
|
|

21.05.2007, 10:49
|
|
Новичок
Регистрация: 04.06.2006
Сообщений: 29
Провел на форуме: 133649
Репутация:
6
|
|
да, вообще задача поставлена именно для выполнения в windows api
|
|
|

21.05.2007, 11:09
|
|
Постоянный
Регистрация: 23.04.2006
Сообщений: 622
Провел на форуме: 5887054
Репутация:
1292
|
|
Сейчас времени уже нету, позже посмотрю внимательнее.
Она кстати у тебя не виснет, просто создаёт диалог но фокус на него не передаёт(без нажатия alt), похоже что фокус остаётся у меню бара, почему я так и не понял...
1) Тело функции обработки диалога зря закоментил.
2) return TRUE не везде возвращяешь.
|
|
|

21.05.2007, 12:21
|
|
Новичок
Регистрация: 04.06.2006
Сообщений: 29
Провел на форуме: 133649
Репутация:
6
|
|
Да, вижу, только вот не понимаю, в чем дело с ALTом и что не рисуются штриховые 
Последний раз редактировалось Visor; 22.05.2007 в 20:03..
|
|
|

22.05.2007, 02:36
|
|
Постоянный
Регистрация: 23.04.2006
Сообщений: 622
Провел на форуме: 5887054
Репутация:
1292
|
|
У тебя с проектом что-то не так, я так и не нашел что, создай новый проект, НЕ КОПИРУЙ диалоговые окна, пункты меню и даже их элементы, не копируй свои функции, делай точно как в заготовке проекта и должно всё работать
Я пробовал создать новый проект, скопировать туда твой диалог и функцию колбэка и получилась та-же чушь, так что НЕ КОПИРУЙ.
Насчёт пунктиров, так функция CreatePen не умеет рисовать пунктиры шире одного пикселя, вроде-бы ExtCreatePen умеет или используй "GDI Plus"
|
|
|

22.05.2007, 19:00
|
|
Постоянный
Регистрация: 08.04.2007
Сообщений: 853
Провел на форуме: 5812656
Репутация:
1540
|
|
блин писал графы правда не win api если понадобяться какие-нить алгоритмы стучи в 213947843 помогу
|
|
|

22.05.2007, 20:44
|
|
Новичок
Регистрация: 04.06.2006
Сообщений: 29
Провел на форуме: 133649
Репутация:
6
|
|
Респект!
Вобщем, с текстом можно так, насколько я понял:
Код:
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 не умеет рисовать пунктиры шире одного пикселя, вроде-бы ExtCreatePen умеет или используй "GDI Plus"
Странно, вроде если брать CreatePen, то можно пользоваться либо PS_SOLID, либо PS_DASH.
Или я тут что-то напутал с CreatePen и ExtCreatePen.
P.S. Половину дня убил на поиски ресурсов по теме.
Нашёл вот эту статью -- вполне информативно!
Ладно, я ещё покопаюсь. Надеюсь, всё же озарение будет  -- тогда обязательно отпишусь!
Последний раз редактировалось Visor; 22.05.2007 в 20:48..
|
|
|

22.05.2007, 21:19
|
|
Постоянный
Регистрация: 23.04.2006
Сообщений: 622
Провел на форуме: 5887054
Репутация:
1292
|
|
Сообщение от Visor
Странно, вроде если брать CreatePen, то можно пользоваться либо PS_SOLID, либо PS_DASH.
Или я тут что-то напутал с CreatePen и ExtCreatePen.
http://msdn2.microsoft.com/en-us/library/aa922162.aspx
If the value specified by nWidth is greater than 1, the fnPenStyle parameter must be PS_NULL or PS_SOLID.
|
|
|
|
 |
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
|
|
|
|