TCanvas w Microsoft Visual C++?
Jesli z togo , chto mne izwestno to w Builder C++ primieniajatsia obiekt TCanvas.
Spasibo za pomosh!
Mozet li mnie kto nibud podskazat kakoj grficheskij obiekt nado primieniat' w Visual C++?
Jesli z togo , chto mne izwestno to w Builder C++ primieniajatsia obiekt TCanvas.
Spasibo za pomosh!
Насколько мне известно, аналога TCanvas в MFC нет. Все функции параметров реализуются через класс CWnd (типа видимый/невидимый объект, положение, размеры), функции рисования через контекст твоего окна (CDC) твоего объекта (типа нарисовать линию).
spasibo za otvet, tolko problema w tom , chto ja ne polzujs' MFC.
А какой же графической библиотекой пользуешься?
В принципе оба класса являются виндовыми, в смысле они не из MFC, так что можешь ими пользоваться и без MFC.
ja i xotela uznat' kakije nuzny biblioteki , potomu shto u mienia kompilator nie nachodit graph.h.
ты включаешь windows.h?
ты включаешь windows.h?
net, ja ne wkluchaju.mozesch mne woobche skazat' chto nado sdelat' chtoby narisowat' chotiaby prostuju liniju?
net, ja ne wkluchaju.mozesch mne woobche skazat' chto nado sdelat' chtoby narisowat' chotiaby prostuju liniju?
если пишешь под винду и делаешь графическое приложение (в смысле не консольное, а с окном), то чтобы рисовать в окне (окно - это может быть любой элемент - кнопка, статический текст на диалоговой форме или просто окно-рамка), тебе надо получить графический контекст окна и рисовать в нем, например так:
dc=GetDC(); //контекст окна, для которого пишешь код, или
dc=Button1.GetDC(); // это если тебе надо контекст, например, Button1
dc->MoveTo(100,100);//переместить курсор в 100,100
dc->LineTo(150,150);//нарисовать линию
dc->ReleaseDC();//освободить контескт, иначе будут утечки памяти
GetDC() определена для класса CWnd, соответственно это все будет работать для классов, наследованных от CWnd.
Второй момент, что это рисование, перерисовка осуществляется по сообщению WM_PAINT, обработчик этого сообщения реализован в OnPaint() или OnDraw(), почитай MSDN чтобы понять разницу.
Смысл, что если ты не переопределишь OnPaint(), все что ты нарисовала будет стираться при перемещении окна, например. Ищи хелп про контексты устройств, вобщем.
Я тут для собственных нужд сваял класс для простейшего канваса - смысл в том, что ты создаешь объект класса, потом в нем рисуешь выбирая цвет, тип и толщину линии. Перерисовка выполняется автоматически, т.е. OnPaint() переопределять не нада. Тока делаешь вызов .LineTo(...) и все автоматически сохраняется. Я этот класс цепляю заместо CStatic на диалоге - и рисую прямо в нем. Функций там всего ничего, но потом можно по желанию самому набить что угодно, сообщения ловит. Если все еще актуально - могу поделиться.
Bolshoje spasibo za pomosh, esli koniechno eto dla Tiebia ne problema to mozesh eto wyslat, mozet prigoditsia w budushem mne ili komu nibud' drugomu...A ja reshila zaniatsia wsio taki Borland C++ Builder :) Spasibo za pomosh esho raz...
Bolshoje spasibo za pomosh, esli koniechno eto dla Tiebia ne problema to mozesh eto wyslat, mozet prigoditsia w budushem mne ili komu nibud' drugomu...A ja reshila zaniatsia wsio taki Borland C++ Builder :) Spasibo za pomosh esho raz...
Не знаю куда отправлять... Вобщем, смысл в следующем. Создаем свой класс, наследуем его от CWnd, с картой обработки сообщений и всеми делами. Чтобы его мона было пользовать в элементах управления, например на диалоге, его нужно зарегистрировать. Делаем что-то типа:
{
static bool is_registered = false;
if(!is_registered) { //Single init allowed
is_registered = true;
WNDCLASS wc;
wc.style=CS_OWNDC;
wc.lpfnWndProc=MyWndProc; //Creation WndProc
wc.hInstance=::AfxGetInstanceHandle();
wc.lpszClassName = _T("Image");
wc.cbClsExtra=0;
wc.cbWndExtra=0;
wc.hIcon=0;
wc.hCursor=0;
wc.hbrBackground=(HBRUSH)::GetStockObject(WHITE_BRUSH);
wc.lpszMenuName=0;
if(!::AfxRegisterClass(&wc)){
return FALSE;
};
};
return TRUE;
};
is_registered - статический член класса.
процедура окна в самом начале файла класса MyWndProc:
{
CWnd* pWnd;
pWnd=CWnd::FromHandlePermanent(hWnd);
if (pWnd==NULL){
pWnd= new CImageV2();
pWnd->Attach(hWnd);
};
LRESULT lResult = AfxCallWndProc(pWnd, hWnd, nMessage,wParam, lParam);
return lResult;
}
Вызываем регистрацию класса при построении объекта:
{
CImageV2::RegisterWndClass();
}
Теперь мы можем цеплять элементы диалога к этому классу. Чтобы избежать проблем при перерисовки, используем виртуальный контекст в памяти, к переменным класса добавляем CDC memDC;
для инициализации элемента добавляем функцию:
{
//Creer le context de la fenetre
CClientDC DC(this);
//Prendre les dimensions de l'element
RECT rect;
GetClientRect(&rect);
//Les dimensions maximales
maxX=rect.right;
maxY=rect.bottom;
//Creer un context virtuel, compatible avec le context de la fenetre
m_memDC.CreateCompatibleDC(&DC);
m_bmp.CreateCompatibleBitmap(&DC,maxX,maxY);
m_memDC.SelectObject(&m_bmp);
//Selectionner la couleur de fond
m_bkBrush.CreateStockObject(BLACK_BRUSH);
m_memDC.SelectObject(&m_bkBrush);
//Mettre le fond
m_memDC.PatBlt(0,0,maxX,maxY,PATCOPY);
//m_memDC.SetMapMode(MM_TEXT);
Scale(0,0,0,0);
ReleaseDC(&DC);
}
maxX,maxY, m_bkBrush - переменные класса. maxX, maxY - размеры окна, m_bkBrush - кисть.
при перерисовке выполняем копирование из виртуального контекста в реальный, а все рисование идет в виртуальный контекст. Функция перерисовки:
{
//CStatic::OnPaint();
CPaintDC pDC(this);
pDC.BitBlt(0,0,maxX,maxY,&m_memDC,0,0,SRCCOPY);
ReleaseDC(&pDC);
}
Вот вобщем-то и все. Только после создания элемента, например в InitInstance() вызывающего класса, надо вызвать инициализацию для нашего элемента.
Для рисования делаем функцию, например:
{
CPen pen(style, nWidth,Color);
m_memDC.SelectObject(&pen);
m_memDC.LineTo(x,y);
InvalidateRect(NULL);
Здесь при вызове этой функции задаем толщину линий, стиль (линия с точками, пунктирная, ...) и цвет как RGB(0,255,0) - чтобы рисовать зеленым.
Дальше аналогично перегружаем остальные функции рисования или изменения состояний окна, например для реализации видимое/невидимое окно можно сделать что-то типа:
{
if(Vis==TRUE){
SetWindowPos(NULL,0,0,0,0,SWP_SHOWWINDOW|SWP_NOMOVE|SWP_NOSIZE);
}else{
SetWindowPos(NULL,0,0,0,0,SWP_HIDEWINDOW|SWP_NOMOVE|SWP_NOSIZE);
};
}
или ту же самую функцию можно реализовать через ShowWindow().
Да, я еще явно вызываю функции связанные с построением или деструкцией окна, в смысле их обработчики.
{
CWnd::OnNcDestroy();
}
int CImageV2::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
return 0;
}