<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Performance bei GUI Drawings]]></title><description><![CDATA[<p>hallo *,</p>
<p>ich habe folgendes programm erstellt:</p>
<pre><code class="language-cpp">// speed hammer.cpp : Defines the entry point for the application.
//

#include &quot;stdafx.h&quot;

#define MAX_LOADSTRING 100
#define IDS_APP_TITLE			103

#define IDR_MAINFRAME			128
#define IDD_SPEEDHAMMER_DIALOG	102
#define IDD_ABOUTBOX			103
#define IDM_ABOUT				104
#define IDM_EXIT				105
#define IDI_SPEEDHAMMER			107
#define IDI_SMALL				108
#define IDC_SPEEDHAMMER			109
#define IDC_MYICON				2
#ifndef IDC_STATIC
#define IDC_STATIC				-1
#endif
// Nächste Standardwerte für neue Objekte
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS

#define _APS_NO_MFC					130
#define _APS_NEXT_RESOURCE_VALUE	129
#define _APS_NEXT_COMMAND_VALUE		32771
#define _APS_NEXT_CONTROL_VALUE		1000
#define _APS_NEXT_SYMED_VALUE		110
#endif
#endif
// 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_SPEEDHAMMER, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance);

	// Perform application initialization:
	if (!InitInstance (hInstance, nCmdShow))
	{
		return FALSE;
	}

	hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_SPEEDHAMMER));

	// Main message loop:
	while (GetMessage(&amp;msg, NULL, 0, 0))
	{
		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &amp;msg))
		{
			TranslateMessage(&amp;msg);
			DispatchMessage(&amp;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_SPEEDHAMMER));
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= NULL;
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

	return RegisterClassEx(&amp;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 | WS_MAXIMIZE,
	   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
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	PAINTSTRUCT ps;
	HDC hdc;

	// create pens and brushes for the background color and drawing color
	HPEN hpenBackground;
	HPEN hpenDrawingColor;
	HBRUSH hbrushFillColor;
	HBRUSH hbrushDeleteColor;

	// this is the timer id. every time we come here in, the timer is stopped with -1
	int iTimerID = -1;				

	// this is the flag to determine the status. '1' means, the drawings are done and
	// we have to erase them, before we do new drawings. declared 'static' to not loose
	// the status every time we come here in
	static int iFlag = 1;

	// this is a buffer for handle with some string. we may re-use this many times and 
	// handle all string operations with this buffer
	static TCHAR text[100];

	// this defines the intervall for the timer
	int iTimer = 10;

	// this is used to get the actual mouse cursor position
	POINT pointMouseCoords;

	// this stores the actual screen size
	RECT rectClientRect;

	// this will store the coords for the cursor
	static int iCursorX1;
	static int iCursorY1;
	static int iCursorX2;
	static int iCursorY2;

	// this stores the 'mode' for the ball; '+' means, the ball moves x+, respective y+
	// additionally, we define here the starting point of the ball
	static char cXmode = '+';
	static char cYmode = '+';
	static int iXBallCoord = 100;
	static int iYBallCoord = 100;

	switch (message)
	{
	case WM_CREATE:
		// here we define a timer. this timer will call WM_TIMER every 'iTimer' milli seconds
		SetTimer(hWnd, iTimerID = 1, iTimer, NULL);
		break;
	case WM_TIMER:
		// here we come in, if the timer 'ticks'
		// all we do here, is send a WM_PAINT message to our own window, so we can draw there
		// the actual screen
		SendMessage(hWnd, WM_PAINT, 0, 0);
		break;
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &amp;ps);
		// first get a device context
		hdc = GetDC(hWnd);
		// get actual screen size
		GetClientRect(hWnd, &amp;rectClientRect);
		// make mouse cursor invisible
		ShowCursor(FALSE);

		// we delete the actual cursor and ball
		hpenBackground = CreatePen(PS_SOLID, -1, RGB(255, 255, 255));
		hbrushDeleteColor = CreateSolidBrush(RGB(255 ,255 ,255));
		SelectObject(hdc, hpenBackground);
		SelectObject(hdc, hbrushDeleteColor);	
		Rectangle(hdc, iCursorX1, iCursorY1, iCursorX2, iCursorY2);
		Ellipse(hdc, iXBallCoord, iYBallCoord, iXBallCoord + 12, iYBallCoord + 12);
		DeleteObject(hpenBackground);
		DeleteObject(hbrushDeleteColor);

		// getting actual mouse coords and calculate coords for cursor
		GetCursorPos(&amp;pointMouseCoords);
		if (pointMouseCoords.x &lt; rectClientRect.left + 75) {
			iCursorX1 = rectClientRect.left + 1;
			iCursorX2 = rectClientRect.left + 151;
		} else if (pointMouseCoords.x &gt; rectClientRect.right - 75) {
			iCursorX1 = rectClientRect.right - 151;
			iCursorX2 = rectClientRect.right - 1;
			} else {
			iCursorX1 = pointMouseCoords.x - 75;
			iCursorX2 = pointMouseCoords.x + 75;
		}
		iCursorY1 = rectClientRect.bottom - 30;
		iCursorY2 = rectClientRect.bottom - 10;

		// calculate actual ball coords
		switch (cXmode) {
			case '+':
				iXBallCoord = iXBallCoord + 1;
				// change mode, if ball hit right side of window
				if (iXBallCoord &gt; rectClientRect.right - 13) {
					cXmode = '-';
				}
				break;
			case '-':
				iXBallCoord = iXBallCoord - 1;
				// change mode, if ball hit left side of window
				if (iXBallCoord &lt; rectClientRect.left + 1) {
					cXmode ='+';
				}
				break;
		}
		switch (cYmode) {
			case '+':
				iYBallCoord = iYBallCoord + 1;
				// change mode, if ball hit the cursor
				if (iYBallCoord == rectClientRect.bottom - 42 
					&amp;&amp; iXBallCoord &gt;= iCursorX1 
					&amp;&amp; iXBallCoord &lt;= iCursorX2) {
					cYmode = '-';
				}
				// 'game over', if ball hit the bottom
				if (iYBallCoord &gt; rectClientRect.bottom - 13) {
					DrawText(hdc, TEXT (&quot;GAME OVER&quot;), -1, &amp;rectClientRect, DT_SINGLELINE | DT_VCENTER | DT_CENTER);
					KillTimer(hWnd, 1); 
				}
				break;
			case '-':
				iYBallCoord = iYBallCoord - 1;
				// change mode, if ball hit top of window
				if (iYBallCoord &lt; rectClientRect.top + 1) {
					cYmode ='+';
				}
				break;
		}

		// draw our actual coursor and ball
		hpenDrawingColor = CreatePen(PS_SOLID, -1, RGB(0, 0, 0));
		SelectObject(hdc, hpenDrawingColor);
		hbrushFillColor = CreateSolidBrush(RGB(0 ,0 ,0));
		SelectObject(hdc, hbrushFillColor);	
		Rectangle(hdc, iCursorX1, iCursorY1, iCursorX2, iCursorY2);
		Ellipse(hdc, iXBallCoord, iYBallCoord, iXBallCoord + 12, iYBallCoord + 12);
		DeleteObject(hpenDrawingColor);
		DeleteObject(hbrushFillColor);

		// release device context
		ReleaseDC(hWnd, hdc);
		EndPaint(hWnd, &amp;ps);
		break;
	case WM_DESTROY:
		// here we kill the timer, because application is closed
		KillTimer(hWnd, 1); 
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0; 
}
</code></pre>
<p>das problem damit ist, das es seeeehr langsam ist.<br />
ich habe folgenden weg gewählt:<br />
ein gesetzter timer ruft meine callback alle 10 ms auf. die callback fängt diesen aufruf in WM_TIMER ab und initiiert ein WM_PAINT. dort findet dann der zeichenvorgang statt. eine weitere verringerung der timer frequenz bringt nichts mehr.</p>
<p>meine frage ist daher: wie kann ich hier die performance erhöhen?<br />
in den faq's habe ich etwas über backbuffering gelesen, ist das vllt. die lösung? oder ist grundsätzlich mein ansatz mit dem timer der falsche weg?</p>
<p>schon mal vielen dank für eure antworten <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<p>gruß pacy</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/234546/performance-bei-gui-drawings</link><generator>RSS for Node</generator><lastBuildDate>Wed, 08 Apr 2026 11:23:53 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/234546.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 19 Feb 2009 10:01:29 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Performance bei GUI Drawings on Thu, 19 Feb 2009 10:01:29 GMT]]></title><description><![CDATA[<p>hallo *,</p>
<p>ich habe folgendes programm erstellt:</p>
<pre><code class="language-cpp">// speed hammer.cpp : Defines the entry point for the application.
//

#include &quot;stdafx.h&quot;

#define MAX_LOADSTRING 100
#define IDS_APP_TITLE			103

#define IDR_MAINFRAME			128
#define IDD_SPEEDHAMMER_DIALOG	102
#define IDD_ABOUTBOX			103
#define IDM_ABOUT				104
#define IDM_EXIT				105
#define IDI_SPEEDHAMMER			107
#define IDI_SMALL				108
#define IDC_SPEEDHAMMER			109
#define IDC_MYICON				2
#ifndef IDC_STATIC
#define IDC_STATIC				-1
#endif
// Nächste Standardwerte für neue Objekte
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS

#define _APS_NO_MFC					130
#define _APS_NEXT_RESOURCE_VALUE	129
#define _APS_NEXT_COMMAND_VALUE		32771
#define _APS_NEXT_CONTROL_VALUE		1000
#define _APS_NEXT_SYMED_VALUE		110
#endif
#endif
// 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_SPEEDHAMMER, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance);

	// Perform application initialization:
	if (!InitInstance (hInstance, nCmdShow))
	{
		return FALSE;
	}

	hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_SPEEDHAMMER));

	// Main message loop:
	while (GetMessage(&amp;msg, NULL, 0, 0))
	{
		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &amp;msg))
		{
			TranslateMessage(&amp;msg);
			DispatchMessage(&amp;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_SPEEDHAMMER));
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= NULL;
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

	return RegisterClassEx(&amp;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 | WS_MAXIMIZE,
	   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
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	PAINTSTRUCT ps;
	HDC hdc;

	// create pens and brushes for the background color and drawing color
	HPEN hpenBackground;
	HPEN hpenDrawingColor;
	HBRUSH hbrushFillColor;
	HBRUSH hbrushDeleteColor;

	// this is the timer id. every time we come here in, the timer is stopped with -1
	int iTimerID = -1;				

	// this is the flag to determine the status. '1' means, the drawings are done and
	// we have to erase them, before we do new drawings. declared 'static' to not loose
	// the status every time we come here in
	static int iFlag = 1;

	// this is a buffer for handle with some string. we may re-use this many times and 
	// handle all string operations with this buffer
	static TCHAR text[100];

	// this defines the intervall for the timer
	int iTimer = 10;

	// this is used to get the actual mouse cursor position
	POINT pointMouseCoords;

	// this stores the actual screen size
	RECT rectClientRect;

	// this will store the coords for the cursor
	static int iCursorX1;
	static int iCursorY1;
	static int iCursorX2;
	static int iCursorY2;

	// this stores the 'mode' for the ball; '+' means, the ball moves x+, respective y+
	// additionally, we define here the starting point of the ball
	static char cXmode = '+';
	static char cYmode = '+';
	static int iXBallCoord = 100;
	static int iYBallCoord = 100;

	switch (message)
	{
	case WM_CREATE:
		// here we define a timer. this timer will call WM_TIMER every 'iTimer' milli seconds
		SetTimer(hWnd, iTimerID = 1, iTimer, NULL);
		break;
	case WM_TIMER:
		// here we come in, if the timer 'ticks'
		// all we do here, is send a WM_PAINT message to our own window, so we can draw there
		// the actual screen
		SendMessage(hWnd, WM_PAINT, 0, 0);
		break;
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &amp;ps);
		// first get a device context
		hdc = GetDC(hWnd);
		// get actual screen size
		GetClientRect(hWnd, &amp;rectClientRect);
		// make mouse cursor invisible
		ShowCursor(FALSE);

		// we delete the actual cursor and ball
		hpenBackground = CreatePen(PS_SOLID, -1, RGB(255, 255, 255));
		hbrushDeleteColor = CreateSolidBrush(RGB(255 ,255 ,255));
		SelectObject(hdc, hpenBackground);
		SelectObject(hdc, hbrushDeleteColor);	
		Rectangle(hdc, iCursorX1, iCursorY1, iCursorX2, iCursorY2);
		Ellipse(hdc, iXBallCoord, iYBallCoord, iXBallCoord + 12, iYBallCoord + 12);
		DeleteObject(hpenBackground);
		DeleteObject(hbrushDeleteColor);

		// getting actual mouse coords and calculate coords for cursor
		GetCursorPos(&amp;pointMouseCoords);
		if (pointMouseCoords.x &lt; rectClientRect.left + 75) {
			iCursorX1 = rectClientRect.left + 1;
			iCursorX2 = rectClientRect.left + 151;
		} else if (pointMouseCoords.x &gt; rectClientRect.right - 75) {
			iCursorX1 = rectClientRect.right - 151;
			iCursorX2 = rectClientRect.right - 1;
			} else {
			iCursorX1 = pointMouseCoords.x - 75;
			iCursorX2 = pointMouseCoords.x + 75;
		}
		iCursorY1 = rectClientRect.bottom - 30;
		iCursorY2 = rectClientRect.bottom - 10;

		// calculate actual ball coords
		switch (cXmode) {
			case '+':
				iXBallCoord = iXBallCoord + 1;
				// change mode, if ball hit right side of window
				if (iXBallCoord &gt; rectClientRect.right - 13) {
					cXmode = '-';
				}
				break;
			case '-':
				iXBallCoord = iXBallCoord - 1;
				// change mode, if ball hit left side of window
				if (iXBallCoord &lt; rectClientRect.left + 1) {
					cXmode ='+';
				}
				break;
		}
		switch (cYmode) {
			case '+':
				iYBallCoord = iYBallCoord + 1;
				// change mode, if ball hit the cursor
				if (iYBallCoord == rectClientRect.bottom - 42 
					&amp;&amp; iXBallCoord &gt;= iCursorX1 
					&amp;&amp; iXBallCoord &lt;= iCursorX2) {
					cYmode = '-';
				}
				// 'game over', if ball hit the bottom
				if (iYBallCoord &gt; rectClientRect.bottom - 13) {
					DrawText(hdc, TEXT (&quot;GAME OVER&quot;), -1, &amp;rectClientRect, DT_SINGLELINE | DT_VCENTER | DT_CENTER);
					KillTimer(hWnd, 1); 
				}
				break;
			case '-':
				iYBallCoord = iYBallCoord - 1;
				// change mode, if ball hit top of window
				if (iYBallCoord &lt; rectClientRect.top + 1) {
					cYmode ='+';
				}
				break;
		}

		// draw our actual coursor and ball
		hpenDrawingColor = CreatePen(PS_SOLID, -1, RGB(0, 0, 0));
		SelectObject(hdc, hpenDrawingColor);
		hbrushFillColor = CreateSolidBrush(RGB(0 ,0 ,0));
		SelectObject(hdc, hbrushFillColor);	
		Rectangle(hdc, iCursorX1, iCursorY1, iCursorX2, iCursorY2);
		Ellipse(hdc, iXBallCoord, iYBallCoord, iXBallCoord + 12, iYBallCoord + 12);
		DeleteObject(hpenDrawingColor);
		DeleteObject(hbrushFillColor);

		// release device context
		ReleaseDC(hWnd, hdc);
		EndPaint(hWnd, &amp;ps);
		break;
	case WM_DESTROY:
		// here we kill the timer, because application is closed
		KillTimer(hWnd, 1); 
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0; 
}
</code></pre>
<p>das problem damit ist, das es seeeehr langsam ist.<br />
ich habe folgenden weg gewählt:<br />
ein gesetzter timer ruft meine callback alle 10 ms auf. die callback fängt diesen aufruf in WM_TIMER ab und initiiert ein WM_PAINT. dort findet dann der zeichenvorgang statt. eine weitere verringerung der timer frequenz bringt nichts mehr.</p>
<p>meine frage ist daher: wie kann ich hier die performance erhöhen?<br />
in den faq's habe ich etwas über backbuffering gelesen, ist das vllt. die lösung? oder ist grundsätzlich mein ansatz mit dem timer der falsche weg?</p>
<p>schon mal vielen dank für eure antworten <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<p>gruß pacy</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1666238</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1666238</guid><dc:creator><![CDATA[pacy]]></dc:creator><pubDate>Thu, 19 Feb 2009 10:01:29 GMT</pubDate></item><item><title><![CDATA[Reply to Performance bei GUI Drawings on Thu, 19 Feb 2009 11:02:54 GMT]]></title><description><![CDATA[<p>Die WinAPI ist nicht für halsbrecherische Geschwindigkeiten gemacht <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /> Wäre vielleicht z.B. eingebettetes OpenGL etwas für dich?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1666291</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1666291</guid><dc:creator><![CDATA[Badestrand]]></dc:creator><pubDate>Thu, 19 Feb 2009 11:02:54 GMT</pubDate></item><item><title><![CDATA[Reply to Performance bei GUI Drawings on Thu, 19 Feb 2009 11:35:00 GMT]]></title><description><![CDATA[<p>Zeichne auf ein Bitmap im Speicher und blitte diesen immer wenn nötig auf den Canvas.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1666312</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1666312</guid><dc:creator><![CDATA[_Luckie]]></dc:creator><pubDate>Thu, 19 Feb 2009 11:35:00 GMT</pubDate></item><item><title><![CDATA[Reply to Performance bei GUI Drawings on Fri, 20 Feb 2009 22:29:00 GMT]]></title><description><![CDATA[<p>danke für die antworten!</p>
<p>das heisst also, dass das mit dem timer gängige praxis ist, ich aber damit an die leistungsgrenzen stoße und es günstiger wäre, die operationen im speicher zu tätigen und nur zu blitten? oder ist meine art und weise schon gänzlich falsch und es gibt eine bessere lösung?</p>
<p>mit opengl oder anderen zusätzlichen dingen wollte ich mich jetzt am anfang eigentlich nicht schon beschäftigen (müssen) <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<p>gruß pacy</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1667365</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1667365</guid><dc:creator><![CDATA[pacy]]></dc:creator><pubDate>Fri, 20 Feb 2009 22:29:00 GMT</pubDate></item><item><title><![CDATA[Reply to Performance bei GUI Drawings on Fri, 20 Feb 2009 23:18:52 GMT]]></title><description><![CDATA[<p>BackBuffer ist bei GDI bei viel Zeichnerei meiner Meinung nach immer gut <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";D"
      alt="😉"
    /><br />
Die GDI-Objekte wie Brushes, Pens, etc. würde ich auch nur einmal erstellen, statt sie jedesmal neu zu erzeugen und gleich wieder zu löschen wenn WM_PAINT aufgerufen wird.</p>
<p>ShowCursor() könnte man bestimmt auch noch auslagern.<br />
GetClientRect() und GetCursorPos() rufen Infos ab die du auch via WM_SIZE bzw. WM_MOUSEMOVE bekommst und nicht bei jedem WM_PAINT aufgerufen werden müssten - Ob das großartig was zur Performance tut bezweifle ich aber mal <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";D"
      alt="😉"
    /></p>
<p>Bei WM_TIMER rufst du WM_PAINT selbst auf, microsoft findet das nich so gut:</p>
<p>msdn schrieb:</p>
<blockquote>
<p>The WM_PAINT message is generated by the system and should not be sent by an application.</p>
</blockquote>
<p>InvalidateRect() + UpdateWindow() wird da meistens eher verwendet.</p>
<p>Der Timer selbst ist übrigens nicht sonderlich genau, kann gut sein das er auch bei kleineren Werten nur alle 10ms loslegt und dein WM_PAINT eigentlich keine 10ms braucht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1667382</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1667382</guid><dc:creator><![CDATA[geeky]]></dc:creator><pubDate>Fri, 20 Feb 2009 23:18:52 GMT</pubDate></item><item><title><![CDATA[Reply to Performance bei GUI Drawings on Sat, 21 Feb 2009 08:40:10 GMT]]></title><description><![CDATA[<p>Grundsätzlich muss ein Objekt, dass selbst erzeugt wurde und in einen DC geladen wurde auch wieder aus dem DC deselekiert werden. Ansonsten bekommst Du auch Speicherleaks.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1667443</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1667443</guid><dc:creator><![CDATA[Martin Richter]]></dc:creator><pubDate>Sat, 21 Feb 2009 08:40:10 GMT</pubDate></item><item><title><![CDATA[Reply to Performance bei GUI Drawings on Thu, 26 Feb 2009 13:37:58 GMT]]></title><description><![CDATA[<p>danke euch!</p>
<p>gruß pacy</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1670651</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1670651</guid><dc:creator><![CDATA[pacy]]></dc:creator><pubDate>Thu, 26 Feb 2009 13:37:58 GMT</pubDate></item></channel></rss>