Новичок
Профиль
Группа: Участник
Сообщений: 9
Регистрация: 13.4.2010
Репутация: нет Всего: нет
|
Пишу простой графический редактор. По заданию необходимо работать с enh-метафайлами. Программа работает так: рисую мышью на форме, попутно рисую всё на метафайл. Чтобы при сворачивании формы изображение не пропадало, обрабатываю сообщение WM_PAINT - закрываю старый метафайл и создаю новый, проигрываю старый в новый и на экран, удаляю старый. Вот проблема: при перемещении или сворачивании формы программа начинает жутко тормозить, а если начать ещё что-нибудь рисовать, так и вообще виснет. Проблема с метафайлами. Вот весь мой код, внимательно посмотрите на обработку WM_PAINT, может тут что не так: Код | // GraphicsEditor.cpp : Defines the entry point for the application. //
#include "stdafx.h" #include <windows.h> #include <CommDlg.h> #include <stdio.h> #include <string.h> #include "GraphicsEditor.h"
#define MAX_LOADSTRING 100 #define ID_BUTTONLINE 1000 #define ID_BUTTTONRECTANGLE 1001 #define ID_BUTTONELLIPSE 1002 #define ID_BUTTONPOLYGON 1003 #define ID_BUTTONPOLYLINE 1004 #define ID_EDIT 1005 #define ID_BUTTONTEXT 1006 #define CM_FILE_OPEN 1007 #define CM_FILE_SAVE 1008 #define FILE_NAME1 "Metafile1.emf" #define FILE_NAME2 "Metafile2.emf"
// Global Variables: HINSTANCE hInst; // current instance TCHAR szTitle[MAX_LOADSTRING]; // The title bar text TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
// Forward declarations of functions included in this code module: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: Place code here. MSG msg; HACCEL hAccelTable;
// Initialize global strings LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_GRAPHICSEDITOR, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance);
// Perform application initialization: if (!InitInstance (hInstance, nCmdShow)) { return FALSE; }
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_GRAPHICSEDITOR));
// Main message loop: while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } }
return (int) msg.wParam; }
// // FUNCTION: MyRegisterClass() // // PURPOSE: Registers the window class. // // COMMENTS: // // This function and its usage are only necessary if you want this code // to be compatible with Win32 systems prior to the 'RegisterClassEx' // function that was added to Windows 95. It is important to call this function // so that the application will get 'well formed' small icons associated // with it. // 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_GRAPHICSEDITOR)); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = MAKEINTRESOURCE(IDC_GRAPHICSEDITOR); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&wcex); }
// // FUNCTION: InitInstance(HINSTANCE, int) // // PURPOSE: Saves instance handle and creates main window // // COMMENTS: // // In this function, we save the instance handle in a global variable and // create and display the main program window. // BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd) { return FALSE; }
ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd);
return TRUE; }
// // FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM) // // PURPOSE: Processes messages for the main window. // // WM_COMMAND - process the application menu // WM_PAINT - Paint the main window // WM_DESTROY - post a quit message and return // //
BOOL CreateMenuItem(HMENU hMenu,char *str,UINT uIns,UINT uCom,HMENU hSubMenu,BOOL flag,UINT fType) { MENUITEMINFO mii; mii.cbSize=sizeof(MENUITEMINFO); mii.fMask=MIIM_STATE|MIIM_TYPE|MIIM_SUBMENU|MIIM_ID; mii.fType=fType; mii.fState=MFS_ENABLED; mii.dwTypeData=str; mii.cch=sizeof(str); mii.wID=uCom; mii.hSubMenu=hSubMenu; return InsertMenuItem(hMenu,uIns,flag,&mii); }
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; PAINTSTRUCT ps; HDC static hdc,hdc1,hdc2; HDC static hdcSaveFile; HWND static hButtonLine,hButtonRectangle,hButtonEllipse,hButtonPolyline,hButtonPolygon,hEdit,hButtonText; int static x0,y0,x1,y1,x2,y2,oldMixMode; HENHMETAFILE hEnhMtf; static bool b,bPoly,bText,flag; static int id; int i; static HBRUSH hBrush; static HPEN hPen; static HMENU hMainMenu,hFileMenu; static OPENFILENAME ofn; static char fullpath[256],filename[256],dir[256]; char lpString[100]; ENHMETAHEADER emh; RECT rect; switch (message) { case WM_CREATE: hdc=GetDC(hWnd); hButtonLine=CreateWindow("button","Line",WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON, 100,100,100,30,hWnd,(HMENU)ID_BUTTONLINE,hInst,NULL); hButtonRectangle=CreateWindow("button","Rectangle",WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON, 100,150,100,30,hWnd,(HMENU)ID_BUTTTONRECTANGLE,hInst,NULL); hButtonEllipse=CreateWindow("button","Ellipse",WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON, 100,200,100,30,hWnd,(HMENU)ID_BUTTONELLIPSE,hInst,NULL); hButtonPolyline=CreateWindow("button","Polyline",WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON, 100,250,100,30,hWnd,(HMENU)ID_BUTTONPOLYLINE,hInst,NULL); hButtonPolygon=CreateWindow("button","Polygon",WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON, 100,300,100,30,hWnd,(HMENU)ID_BUTTONPOLYGON,hInst,NULL); hEdit=CreateWindow("edit",NULL,WS_VISIBLE|WS_CHILD|WS_BORDER, 100,350,100,20,hWnd,(HMENU)ID_EDIT,hInst,NULL); hButtonText=CreateWindow("button","Text",WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON, 100,380,100,30,hWnd,(HMENU)ID_BUTTONTEXT,hInst,NULL); hMainMenu=CreateMenu(); hFileMenu=CreatePopupMenu(); i=0; CreateMenuItem(hFileMenu,"&Open",i++,CM_FILE_OPEN,NULL,FALSE,MFT_STRING); CreateMenuItem(hFileMenu,"&Save",i++,CM_FILE_SAVE,NULL,FALSE,MFT_STRING); i=0; CreateMenuItem(hMainMenu,"&File",i++,0,hFileMenu,FALSE,MFT_STRING); SetMenu(hWnd,hMainMenu); DrawMenuBar(hWnd); GetClientRect(hWnd,&rect); hdc1=CreateEnhMetaFile(NULL,NULL,NULL,NULL); flag=false; hBrush=(HBRUSH)GetStockObject(NULL_BRUSH); SelectObject(hdc,hBrush); hPen=(HPEN)GetStockObject(BLACK_PEN); SelectObject(hdc,hPen); SelectObject(hdc1,hBrush); SelectObject(hdc1,hPen); break; case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // Parse the menu selections: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); case ID_BUTTONLINE: //MessageBox(hWnd,"Нажата кнопка Line","Message",0); //SendMessage(hWnd,WM_PAINT,0,0); //UpdateWindow(hWnd); id=ID_BUTTONLINE; break; case ID_BUTTONELLIPSE: id=ID_BUTTONELLIPSE; break; case ID_BUTTTONRECTANGLE: id=ID_BUTTTONRECTANGLE; break; case ID_BUTTONPOLYLINE: id=ID_BUTTONPOLYLINE; break; case ID_BUTTONPOLYGON: id=ID_BUTTONPOLYGON; break; case ID_BUTTONTEXT: id=ID_BUTTONTEXT; break; case CM_FILE_OPEN: ofn.lStructSize=sizeof(OPENFILENAME); ofn.hwndOwner=hWnd; ofn.hInstance=hInst; // дескриптор копии приложения ofn.lpstrFilter="Metafile (*.emf)\0*.emf\0Все файлы (*.*)\0*.*\0"; ofn.nFilterIndex=1; ofn.lpstrFile=fullpath; ofn.nMaxFile=sizeof(fullpath); ofn.lpstrFileTitle=filename; ofn.nMaxFileTitle=sizeof(filename); ofn.lpstrInitialDir=dir; ofn.lpstrTitle="Open file..."; ofn.Flags=OFN_EXPLORER|OFN_CREATEPROMPT|OFN_ALLOWMULTISELECT; if(GetOpenFileName(&ofn)) { hdc1=CreateEnhMetaFile(NULL,NULL,NULL,NULL); hEnhMtf=GetEnhMetaFile(fullpath); GetEnhMetaFileHeader(hEnhMtf,sizeof(ENHMETAHEADER),&emh); SetRect(&rect,emh.rclBounds.left,emh.rclBounds.top,emh.rclBounds.right,emh.rclBounds.bottom); SelectObject(hdc1,hBrush); SelectObject(hdc1,hPen); PlayEnhMetaFile(hdc1,hEnhMtf,&rect); PlayEnhMetaFile(hdc,hEnhMtf,&rect);
InvalidateRect(hWnd,NULL,TRUE); UpdateWindow(hWnd); DeleteEnhMetaFile(hEnhMtf); } break; case CM_FILE_SAVE: ofn.lStructSize=sizeof(OPENFILENAME); ofn.hwndOwner=hWnd; ofn.hInstance=hInst; // дескриптор копии приложения ofn.lpstrFilter="Metafile (*.emf)\0*.emf\0Все файлы (*.*)\0*.*\0"; ofn.nFilterIndex=1; ofn.lpstrFile=fullpath; ofn.nMaxFile=sizeof(fullpath); ofn.lpstrFileTitle=filename; ofn.nMaxFileTitle=sizeof(filename); ofn.lpstrInitialDir=dir; ofn.lpstrTitle="Save file as..."; ofn.Flags=OFN_PATHMUSTEXIST|OFN_OVERWRITEPROMPT|OFN_HIDEREADONLY|OFN_EXPLORER; if(GetSaveFileName(&ofn)) { hEnhMtf=CloseEnhMetaFile(hdc1); CopyEnhMetaFile(hEnhMtf,fullpath); hdc1=CreateEnhMetaFile(NULL,NULL,NULL,NULL); GetEnhMetaFileHeader(hEnhMtf,sizeof(ENHMETAHEADER),&emh); SetRect(&rect,emh.rclBounds.left,emh.rclBounds.top,emh.rclBounds.right,emh.rclBounds.bottom); SelectObject(hdc1,hBrush); SelectObject(hdc1,hPen); PlayEnhMetaFile(hdc1,hEnhMtf,&rect); PlayEnhMetaFile(hdc,hEnhMtf,&rect); DeleteEnhMetaFile(hEnhMtf); } break; default: id=0; return DefWindowProc(hWnd, message, wParam, lParam); } break; case WM_MOUSEMOVE: if(b&&(bPoly==false)) { SetROP2(hdc,R2_NOTXORPEN); switch(id) { case ID_BUTTONLINE: MoveToEx(hdc,x1,y1,NULL); LineTo(hdc,x2,y2); x2=LOWORD(lParam); y2=HIWORD(lParam); MoveToEx(hdc,x1,y1,NULL); LineTo(hdc,x2,y2); break; case ID_BUTTTONRECTANGLE: Rectangle(hdc,x1,y1,x2,y2); x2=LOWORD(lParam); y2=HIWORD(lParam); Rectangle(hdc,x1,y1,x2,y2); break; case ID_BUTTONELLIPSE: Ellipse(hdc,x1,y1,x2,y2); x2=LOWORD(lParam); y2=HIWORD(lParam); Ellipse(hdc,x1,y1,x2,y2); break; }
} if(b&&bPoly) { SetROP2(hdc,R2_NOTXORPEN); MoveToEx(hdc,x1,y1,NULL); LineTo(hdc,x2,y2); x2=LOWORD(lParam); y2=HIWORD(lParam); MoveToEx(hdc,x1,y1,NULL); LineTo(hdc,x2,y2); } break; case WM_LBUTTONDOWN: switch(id) { case ID_BUTTONELLIPSE: case ID_BUTTONLINE: case ID_BUTTTONRECTANGLE: x1=x2=LOWORD(lParam); y1=y2=HIWORD(lParam); if((id==ID_BUTTONLINE)) MoveToEx(hdc,x1,y1,NULL); break; case ID_BUTTONPOLYLINE: case ID_BUTTONPOLYGON: if(bPoly==false) { x0=x1=x2=LOWORD(lParam); y0=y1=y2=HIWORD(lParam); bPoly=true; } break; break; case ID_BUTTONTEXT: x1=x2=LOWORD(lParam); y1=y2=HIWORD(lParam); bText=true; } b=true; break; case WM_RBUTTONUP: if(bPoly) { SetROP2(hdc,R2_COPYPEN); MoveToEx(hdc,x1,y1,NULL); x2=LOWORD(lParam); y2=HIWORD(lParam); LineTo(hdc,x2,y2); MoveToEx(hdc1,x1,y1,NULL); LineTo(hdc1,x2,y2); if(id==ID_BUTTONPOLYGON) { LineTo(hdc,x0,y0); LineTo(hdc1,x0,y0); } bPoly=false; }
case WM_LBUTTONUP: if(b&&(bPoly==false)&&(bText==false)) { SetROP2(hdc,R2_COPYPEN); x2=LOWORD(lParam); y2=HIWORD(lParam); switch (id) { case ID_BUTTONLINE: MoveToEx(hdc,x1,y1,NULL); LineTo(hdc,x2,y2); MoveToEx(hdc1,x1,y1,NULL); LineTo(hdc1,x2,y2); break; case ID_BUTTONELLIPSE: Ellipse(hdc,x1,y1,x2,y2); Ellipse(hdc1,x1,y1,x2,y2); break; case ID_BUTTTONRECTANGLE: Rectangle(hdc,x1,y1,x2,y2); Rectangle(hdc1,x1,y1,x2,y2); break; } b=false; } if(b&&bPoly) { SetROP2(hdc,R2_COPYPEN); MoveToEx(hdc,x1,y1,NULL); MoveToEx(hdc1,x1,y1,NULL); x2=LOWORD(lParam); y2=HIWORD(lParam); LineTo(hdc,x2,y2); LineTo(hdc1,x2,y2); x1=x2; y1=y2; b=false; } if(b&&bText) { SendMessage(hEdit,EM_GETLINE,0,(LPARAM)lpString); TextOut(hdc,LOWORD(lParam),HIWORD(lParam),lpString,strlen(lpString)); TextOut(hdc1,LOWORD(lParam),HIWORD(lParam),lpString,strlen(lpString)); b=false; bText=false; } break; case WM_PAINT: hdc2 = BeginPaint(hWnd, &ps); // TODO: Add any drawing code here... hEnhMtf=CloseEnhMetaFile(hdc1); GetEnhMetaFileHeader(hEnhMtf,sizeof(ENHMETAHEADER),&emh); SetRect(&rect,emh.rclBounds.left,emh.rclBounds.top,emh.rclBounds.right,emh.rclBounds.bottom); hdc1=CreateEnhMetaFile(NULL,NULL,NULL,NULL); PlayEnhMetaFile(hdc2,hEnhMtf,&rect); SelectObject(hdc1,hBrush); SelectObject(hdc1,hPen); PlayEnhMetaFile(hdc1,hEnhMtf,&rect); DeleteEnhMetaFile(hEnhMtf); EndPaint(hWnd, &ps); break; case WM_DESTROY: ReleaseDC(hWnd,hdc); //hEnhMtf=CloseEnhMetaFile(hdc1); //DeleteEnhMetaFile(hEnhMtf); PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
// Message handler for about box. INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE;
case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; }
|
|