Bitmap Button s vlastním textem WinCE – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Bitmap Button s vlastním textem WinCE – C / C++ – Fórum – Programujte.comBitmap Button s vlastním textem WinCE – C / C++ – Fórum – Programujte.com

 

TomyB
~ Anonymní uživatel
57 příspěvků
25. 3. 2018   #1
-
0
-

Ahoj, vytvářím vlastní button s bitmapou a textem, žel text se mi tam nedaří dostat tak jak bych chtěl.

Bitmapa se mi vykreslí, když dále použiji DrawText, tak i text vidím, ale Bitmapa chybí, když okno překruju jiným, nebo ho minimalizuji, tak po obnoveni vidim bitmapu a text zmizne.

Jak tak prosím dostat text natrvalo?

Vykresluji to v WM_TIMER

HINSTANCE hInst = GetModuleHandle(NULL);

hButton = CreateWindow(L"STATIC", g_Id, WS_CHILD | WS_VISIBLE | SS_BITMAP | SS_NOTIFY, g_X, g_Y, 263, 182, hWnd, (HMENU) 1, hInst, NULL);
										HBITMAP hBmp = (HBITMAP)SHLoadDIBitmap(g_ImageNormal);
							
SendMessage(hButton, STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hBmp);
							
RECT rt1 = {0};
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hButton, &ps);

GetClientRect(hButton, &rt1);
RECT rt = {rt1.left + 1, rt1.top + 1, rt1.right - 1, rt1.bottom -1 };
SetBkMode(hdc, TRANSPARENT);
SetTextColor(hdc, 0x0000FF00);

static TCHAR title[] = _T("Button A");
							
DrawText(hdc, title, _tcslen(title), &rt, DT_LEFT | DT_TOP);
EndPaint(hButton, &ps);

Díky za radu

Nahlásit jako SPAM
IP: 94.113.172.–
Radek Chalupa
~ Redaktor
+1
Super člen
25. 3. 2018   #2
-
0
-

#1 TomyB
Z té části kódu tipuji že to vykreslení textu provádíš pouze jednou po vytvoření buttonu, takže když je třeba okno překreslit, vykreslí se automaticky pouze bitmapa která je tomu buttonu přiřazená. Překreslení oken funguje tak že při potřebě překreslení dostane zprávu WM_PAINT a v její obsluze musí být voláno: BeiginPaint - kód vykreslující "vnitřek", tj. klientskou oblast okna - EndPaint.

Jinak v tomhle případě bych použil tzv. "owner-draw" button. Příklad najdeš např. zde: https://www.radekchalupa.cz/…e-winapi/27/

Popř. o principu překreslování zde: https://www.radekchalupa.cz/…se-winapi/4/

Radek Chalupa
- individuální konzultace, školení programování, (C/C++, C#, WinAPI, .NET, COM, ATL, MFC...)
- vývoj software na zakázku
http://www.radekchalupa.cz

Nahlásit jako SPAM
IP: 89.177.51.–
TomyB
~ Anonymní uživatel
57 příspěvků
25. 3. 2018   #3
-
0
-

Na OWNERDRAW už to předělávám, ve výsledku už to funguje jak bych potřeboval, jen to problikává, resp pozadí buttonu problikává.

Příklady si u vás ještě prostuduju.

Díky

Nahlásit jako SPAM
IP: 94.113.172.–
TomyB
~ Anonymní uživatel
57 příspěvků
25. 3. 2018   #4
-
0
-

Tak jsem to prošel s vaším příkladem, mám to shodne, přec to stále problikává. Já to tlačítkou tedy nemám v resources ale dynamicky generuji přes

hButton = CreateWindowEx(NULL, L"button", g_Id, WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON | BS_OWNERDRAW, g_X, g_Y, 263, 182, hWnd, (HMENU) 1, hInst, NULL);
Nahlásit jako SPAM
IP: 94.113.172.–
Radek Chalupa
~ Redaktor
+1
Super člen
26. 3. 2018   #5
-
0
-

#4 TomyB
V jaké situaci to problikává?

Zkus tomu oknu na kterém je button do stylu přidat WS_CLIPCHILDREN.

Veškerý kód kterým kreslíš ten button musí být pouze v obsluze WM_DRAWITEM. Také je možné že kreslíš do toho hlavního okna (na WM_PAINT) a při tom kreslíš i na pozici buttonu, což by ale měl vyřešit ten styl WS_CLIPCHILDREN.

Radek Chalupa
- individuální konzultace, školení programování, (C/C++, C#, WinAPI, .NET, COM, ATL, MFC...)
- vývoj software na zakázku
http://www.radekchalupa.cz

Nahlásit jako SPAM
IP: 89.177.51.–
TomyB
~ Anonymní uživatel
57 příspěvků
26. 3. 2018   #6
-
0
-

#5 Radek Chalupa
WS_CLIPCHILDREN nepomáhá. Zkusil jsem i vytvořit vlastní wndproc pro ten button, ale nelze v ní odchytit WM_ITEMDRAW.

Pod tím vloženým pozadím problikne ta původní šedá plocha buttonu, tak jak jej windows standardne zobrazi. Ať již pohybem okna, nebo kliknutím na tlačítka.

:-(

Nahlásit jako SPAM
IP: 94.113.172.–
gna
~ Anonymní uživatel
1891 příspěvků
26. 3. 2018   #7
-
0
-

Tak to máš úplně blbě.

Zpráva pro překreslení je WM_PAINT. Při "owner draw" dělá překreslení owner při WM_DRAWITEM. Button sám umí zobrazit bitmapu i text. BM_SETIMAGE

Nahlásit jako SPAM
IP: 213.211.51.–
gna
~ Anonymní uživatel
1891 příspěvků
26. 3. 2018   #8
-
0
-

Ale to asi nebude to, co chceš. Tak ukaž, jak to překresluješ.

Nahlásit jako SPAM
IP: 213.211.51.–
Radek Chalupa
~ Redaktor
+1
Super člen
26. 3. 2018   #9
-
0
-

#6 TomyB
WM_DRAWITEM  nedostane ten button ale jeho rodičovské okno (c zadáš jako parent při createwindowex);

každopádně bez kódu těžko radit..

Nahlásit jako SPAM
IP: 89.177.51.–
TomyB
~ Anonymní uživatel
57 příspěvků
26. 3. 2018   #10
-
0
-

#9 Radek Chalupa
Okno
 

ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR g_WindowClass)
{
	WNDCLASS	wc;

    wc.style			= CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc		= (WNDPROC) WndProc;
    wc.cbClsExtra		= 0;
    wc.cbWndExtra		= 0;
    wc.hInstance		= hInstance;
    wc.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MAIN));
    wc.hCursor			= 0;
    wc.hbrBackground	= (HBRUSH) GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName		= 0;
    wc.lpszClassName	= g_WindowClass;

	return RegisterClass(&wc);
}


BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
	hInst = hInstance;
	LoadString(hInstance, IDS_APP_CLASS, g_WindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance, g_WindowClass);

	LoadString(hInstance, IDS_APP_TITLE, g_Title, MAX_LOADSTRING);

	hWnd = CreateWindow(g_WindowClass, g_Title, nCmdShow != SW_HIDE ? WS_VISIBLE : 0,
		CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);

	if (!hWnd)
	{
		return FALSE;
	}

	return TRUE;
}


int WINAPI WinMain(	HINSTANCE hInstance,
					HINSTANCE hPrevInstance,
					LPTSTR    lpCmdLine,
					int       nCmdShow)
{
	if (!InitInstance (hInstance, nCmdShow)) 
	{
		return FALSE;
	}

	MSG msg;

	while (GetMessage(&msg, NULL, 0, 0)) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return msg.wParam;
}


WndProc

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	...
	switch (message)
	{
		....
		case WM_CREATE:
			if (config->settings().background != NULL)
			{
				hBackground = (HBITMAP)SHLoadDIBitmap(config->settings().background);
				if (hBackground == NULL)
				{
					....
				}
			}
			SetTimer(hWnd, TIMER_SECTION_START, 0, NULL);

			break;
                case WM_PAINT:
		{
			RECT rt1 = {0};
			PAINTSTRUCT ps;
			HDC hdc = BeginPaint(hWnd, &ps);
                        HDC hdcMem = CreateCompatibleDC(hdc);
			HGDIOBJ oldBitmap = SelectObject(hdcMem, hBackground);
			BITMAP bitmap;
			GetObject(hBackground, sizeof(bitmap), &bitmap);
			BitBlt(hdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, hdcMem, 0, 0, SRCCOPY);
			SelectObject(hdcMem, oldBitmap);
			DeleteDC(hdcMem);

			EndPaint(hWnd, &ps);

			break;
		}

                case WM_TIMER:
		{
                	KillTimer(hWnd, wParam);

                 	if (wParam == TIMER_SECTION_START)
			{
				section = config->nextSection();
				if (section == NULL)
				{
					....
					break;
				}
				switch (section->type)
				{
					case Config::esec::button:
						unsigned short * g_ImageNormal;
						unsigned long g_X;
						unsigned long g_Y;
						unsigned short * g_Id;
						
						for (unsigned long i = 0; i < section->argc; ++i)
						{
							
							if (section->args[i].type == Config::earg::x)
							{
								g_X = section->args[i].ulValue;
							}
							else if (section->args[i].type == Config::earg::y)
							{
								g_Y = section->args[i].ulValue;
							}
							else if (section->args[i].type == Config::earg::id)
							{
								g_Id = section->args[i].szValue;
							}
						}
						HINSTANCE hInst = GetModuleHandle(NULL);
						hButton = CreateWindowEx(NULL, L"button", g_Id, WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON | BS_OWNERDRAW, g_X, g_Y, 263, 182, hWnd, (HMENU)1, hInst, NULL);
						SetTimer(hWnd, TIMER_SECTION_START, 0, NULL);
						break;
				}
			}
			break;
		}
		case WM_DRAWITEM:
			On_DrawItem((LPDRAWITEMSTRUCT)lParam);
			break;
		....
	}
	return 0;
}

Kresba buttonu

void On_DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
	HBRUSH hbPozadi = CreatePatternBrush(LoadBitmap(hInst, MAKEINTRESOURCE(IDB_POZADI)));

InflateRect(&lpDIS->rcItem, 0,0);
  FillRect(lpDIS->hDC, &lpDIS->rcItem, hbPozadi);
  SetBkMode(lpDIS->hDC, TRANSPARENT);
  SetTextColor(lpDIS->hDC, 0x00A0FFFF);
  switch ( lpDIS->CtlID )
  {
    case 1:
        lpDIS->rcItem.top = lpDIS->rcItem.bottom - 50;
      DrawText(lpDIS->hDC, TEXT("TEST BUTTON"), -1, &lpDIS->rcItem,
        DT_SINGLELINE | DT_CENTER | DT_VCENTER);
      break;
  }
  DeleteObject(hbPozadi);
}
Nahlásit jako SPAM
IP: 94.113.172.–
Radek Chalupa
~ Redaktor
+1
Super člen
26. 3. 2018   #11
-
0
-

#10 TomyB
Není to tím timerem? jaký je interval? takhle na zběžný pohled nevím proč na timer vždy vytváříš button...

Nicméně pokud tou bitmapou v obsluze WM_PAINT vyplnuješ celé okno, pak bys měl nastavit HBRUSH okna na NULL nebo vrátit 0 na zprávu WM_ERASEBKGND. Při požadavku na překreslení totiž před WM_PAINT přijde WM_ERASEBKGND která pokud ji pustíš k defaultnímu zpracování, vyplní kl. oblast tím nastavený štětcem a z toho plyne probliknutí při každém překrelení. Zkus do procedury okna dát:

case WM_ERASEBKGND:

  return 0;

Radek Chalupa
- individuální konzultace, školení programování, (C/C++, C#, WinAPI, .NET, COM, ATL, MFC...)
- vývoj software na zakázku
http://www.radekchalupa.cz

Nahlásit jako SPAM
IP: 89.177.51.–
TomyB
~ Anonymní uživatel
57 příspěvků
26. 3. 2018   #12
-
0
-

#11 Radek Chalupa
přidáním WM_ERASEBKGND žádná změna.

Timer je tam z toho důvodu, že prochází config a najde všechny buttony předem načtené z konfiguračního souboru, když nastevení odpovídá buttonu, tak jej založí, pak se ukončí.

Timer je nastaven na 0.

Např. založí 6 tlačítek s různou pozicí a ukončí se.

Nahlásit jako SPAM
IP: 94.113.172.–
TomyB
~ Anonymní uživatel
57 příspěvků
26. 3. 2018   #13
-
0
-

#11 Radek Chalupa
Tak jsem tam vlozil toto

case WM_CTLCOLORBTN:
            HBRUSH hBrushBtn;
            hBrushBtn = (HBRUSH) GetStockObject(NULL_BRUSH);
            SetBkMode((HDC) wParam, TRANSPARENT);
    return ((LRESULT) hBrushBtn);

a hle, ono už to nebliká, pozadí sedí jak přišitý :-), co ale problikává ještě, je text na buttonu :-(

Nahlásit jako SPAM
IP: 94.113.172.–
Radek Chalupa
~ Redaktor
+1
Super člen
27. 3. 2018   #14
-
0
-

#13 TomyB
Bliká i v klidu nebo při roztahování okna? V té obsluze timeru ho na konci zase spouštíš, takže pokud v tom switchi (lepší by bylo mít tam jen if, když testuješ jedinou hodnotu) bude vždy ta testovaná hodnota, tak se bude opakovaně vytvářet ten button..

Nahlásit jako SPAM
IP: 89.177.51.–
TomyB
~ Anonymní uživatel
57 příspěvků
27. 3. 2018   #15
-
0
-

Problikne to při přesunu okna, při překrytí okna jiným a odsunutí, při kliknutí na button.

Udělal jsem úplně čístý app, jen s pozadim a dvema buttony, a i v tomto čístém příkladu to bliká.

#include "stdafx.h"
#include "Buttons.h"

#define MAX_LOADSTRING 100

HINSTANCE			hInst;
HWND				hwndCB;

ATOM				MyRegisterClass	(HINSTANCE, LPTSTR);
BOOL				InitInstance	(HINSTANCE, int);
LRESULT CALLBACK	WndProc			(HWND, UINT, WPARAM, LPARAM);

HBITMAP				hBackground = NULL;

int WINAPI WinMain(	HINSTANCE hInstance,
					HINSTANCE hPrevInstance,
					LPTSTR    lpCmdLine,
					int       nCmdShow)
{
	MSG msg;

	if (!InitInstance (hInstance, nCmdShow)) 
	{
		return FALSE;
	}

	while (GetMessage(&msg, NULL, 0, 0)) 
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return msg.wParam;
}

ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass)
{
	WNDCLASS	wc;

    wc.style			= CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc		= (WNDPROC) WndProc;
    wc.cbClsExtra		= 0;
    wc.cbWndExtra		= 0;
    wc.hInstance		= hInstance;
    wc.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_BUTTONS));
    wc.hCursor			= 0;
    wc.hbrBackground	= (HBRUSH) GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName		= 0;
    wc.lpszClassName	= szWindowClass;

	return RegisterClass(&wc);
}


BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
	HWND	hWnd;
	TCHAR	szTitle[MAX_LOADSTRING];
	TCHAR	szWindowClass[MAX_LOADSTRING];

	hInst = hInstance;

	LoadString(hInstance, IDC_BUTTONS, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance, szWindowClass);

	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU,
		CW_USEDEFAULT, CW_USEDEFAULT, 800, 480, NULL, NULL, hInstance, NULL);

	if (!hWnd)
	{	
		return FALSE;
	}

	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);

	return TRUE;
}

void On_DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
	HBRUSH hbPozadi = CreatePatternBrush(LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BUTTON)));
   
	InflateRect(&lpDIS->rcItem, 0,0);
	FillRect(lpDIS->hDC, &lpDIS->rcItem, hbPozadi);
	SetBkMode(lpDIS->hDC, TRANSPARENT);
	SetTextColor(lpDIS->hDC, 0x00A0FFFF);
	switch ( lpDIS->CtlID )
	{
    case 1:
		lpDIS->rcItem.top = lpDIS->rcItem.bottom - 50;
		DrawText(lpDIS->hDC, TEXT("BUTTON A"), -1, &lpDIS->rcItem,
			DT_SINGLELINE | DT_CENTER | DT_VCENTER);
		break;
	case 2:
		lpDIS->rcItem.top = lpDIS->rcItem.bottom - 50;
		DrawText(lpDIS->hDC, TEXT("BUTTON B"), -1, &lpDIS->rcItem,
			DT_SINGLELINE | DT_CENTER | DT_VCENTER);
		break;
	}
	DeleteObject(hbPozadi);
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	HDC hdc;
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	TCHAR szHello[MAX_LOADSTRING];

	switch (message) 
	{
		case WM_COMMAND:
			wmId    = LOWORD(wParam); 
			wmEvent = HIWORD(wParam); 
			switch (wmId)
			{
				case 1:

					break;
				case 2:

					break;
				default:
				   return DefWindowProc(hWnd, message, wParam, lParam);
			}
			break;
		case WM_ERASEBKGND:
			return 0;
			break;
		case WM_CREATE:
			hBackground = (HBITMAP)LoadBitmap(hInst, MAKEINTRESOURCE(IDB_POZADI));
			break;
		case WM_PAINT:
			RECT rt;
			hdc = BeginPaint(hWnd, &ps);

			if (hBackground==NULL) {

				GetClientRect(hWnd, &rt);
			
				LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
				DrawText(hdc, szHello, _tcslen(szHello), &rt, 
				DT_SINGLELINE | DT_VCENTER | DT_CENTER);
			} else {

				HDC hdcMem = CreateCompatibleDC(hdc);
				HGDIOBJ oldBitmap = SelectObject(hdcMem, hBackground);
				BITMAP bitmap;
				GetObject(hBackground, sizeof(bitmap), &bitmap);
				BitBlt(hdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, hdcMem, 0, 0, SRCCOPY);
				SelectObject(hdcMem, oldBitmap);
				DeleteDC(hdcMem);
			}

			EndPaint(hWnd, &ps);

			CreateWindowEx(NULL, L"button", TEXT("Button 1"), WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON | BS_OWNERDRAW, 1, 50, 160, 120, hWnd, (HMENU)1, hInst, NULL);
			CreateWindowEx(NULL, L"button", TEXT("Button 2"), WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON | BS_OWNERDRAW, 1, 175, 160, 120, hWnd, (HMENU)2, hInst, NULL);

			break;
		case WM_DRAWITEM:
			On_DrawItem((LPDRAWITEMSTRUCT)lParam);
			break;
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
   }
   return 0;
}
Nahlásit jako SPAM
IP: 94.113.172.–
Radek Chalupa
~ Redaktor
+1
Super člen
27. 3. 2018   #16
-
0
-

#15 TomyB
to vytváříš ty 2 buttony v obsluze WM_PAINT? to by byl důvod toho blikání.  nebo v tom kódu něco vypadlo?

Nahlásit jako SPAM
IP: 89.177.51.–
TomyB
~ Anonymní uživatel
57 příspěvků
27. 3. 2018   #17
-
0
-

#16 Radek Chalupa

V původním kódu v obsluze WM_CREATE volám WM_TIMER a to tolikrát kolikrát najde v konfiguračním souboru udaje s hodnotami buttonu (soubor podobný INI, [button] x=1, y=1 [button] x=1, y=100 atd), které se mají vykreslit. Možná bych to mohl předělat na cykl a nemusel ten WM_TIMER volat několikrat po sobě.

No nicméně v tom novém očištěném kódu ty buttony vytvářím ve WM_PAINT, zkoušel jsem i WM_CREATE, v obou případech se to chová stejně.

Dělám něco špatně, kde to tedy má být?

Nahlásit jako SPAM
IP: 94.113.172.–
Radek Chalupa
~ Redaktor
+1
Super člen
27. 3. 2018   #18
-
0
-

#17 TomyB
Určitě bych to nedával do wm_paint a samozřejmě ověřit si že se ten timer nějak nezacyklí...

Zkusil jsem to podobně a žádné blikání jsem nezaregistroval. Rozdíl je jen v tom že ty štetce vytvořím na začátku a mám je jakoglobální proměnné a ve wm_paint míst BitBlt  jsem použil Fillrect. viz kód

#include "stdafx.h"
#include "uk-button.h"

#define MAX_LOADSTRING 100

// Global Variables:
HINSTANCE hInst;                                // current instance
WCHAR szTitle[MAX_LOADSTRING];                  // The title bar text
WCHAR szWindowClass[MAX_LOADSTRING];            // the main window class name
HBRUSH _hb_pozadi = NULL;
HBRUSH _hb_okno = NULL;

// Forward declarations of functions included in this code module:
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
void wm_draw_item(DRAWITEMSTRUCT* dis) noexcept;

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // TODO: Place code here.

    // Initialize global strings
    LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadStringW(hInstance, IDC_UKBUTTON, szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance);

	_hb_pozadi = CreatePatternBrush(LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BUTTON)));
	_hb_okno = CreatePatternBrush(LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_POZADI)));
	// Perform application initialization:
    if (!InitInstance (hInstance, nCmdShow))
    {
        return FALSE;
    }

    HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_UKBUTTON));

    MSG msg;

    // Main message loop:
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return (int) msg.wParam;
}

ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEXW 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_UKBUTTON));
    wcex.hCursor        = LoadCursor(nullptr, IDC_ARROW);
	wcex.hbrBackground = (HBRUSH)NULL;// (COLOR_WINDOW + 1);
    wcex.lpszMenuName   = MAKEINTRESOURCEW(IDC_UKBUTTON);
    wcex.lpszClassName  = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassExW(&wcex);
}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   hInst = hInstance; // Store instance handle in our global variable

   HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);

   if (!hWnd)
   {
      return FALSE;
   }
   CreateWindowEx(NULL, L"button", L"", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_OWNERDRAW, 100, 100, 128, 128, hWnd, (HMENU)1, hInst, NULL);
   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);
   return TRUE;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_COMMAND:
        {
            int wmId = LOWORD(wParam);
            // Parse the menu selections:
            switch (wmId)
            {
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
        }
        break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
			RECT rect;
			GetClientRect(hWnd, &rect);
			FillRect(hdc, &rect, _hb_okno);
            EndPaint(hWnd, &ps);
        }
        break;
	case WM_DRAWITEM:
		wm_draw_item((DRAWITEMSTRUCT*)lParam);
		break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

void wm_draw_item(DRAWITEMSTRUCT* lpDIS) noexcept
{
	if (lpDIS->itemState & ODS_SELECTED)
		DrawFrameControl(lpDIS->hDC, &lpDIS->rcItem, DFC_BUTTON, DFCS_BUTTONPUSH | DFCS_PUSHED);
	else
		DrawFrameControl(lpDIS->hDC, &lpDIS->rcItem, DFC_BUTTON, DFCS_BUTTONPUSH);
	InflateRect(&lpDIS->rcItem, -4, -4);
	FillRect(lpDIS->hDC, &lpDIS->rcItem, _hb_pozadi);
	SetBkMode(lpDIS->hDC, TRANSPARENT);
	SetTextColor(lpDIS->hDC, 0x00A0FFFF);
	DrawText(lpDIS->hDC, L"Tlačítko", -1, &lpDIS->rcItem,
		DT_SINGLELINE | DT_CENTER | DT_VCENTER);
}

jinak je to ve windows 10

Radek Chalupa
- individuální konzultace, školení programování, (C/C++, C#, WinAPI, .NET, COM, ATL, MFC...)
- vývoj software na zakázku
http://www.radekchalupa.cz

Nahlásit jako SPAM
IP: 89.177.51.–
Radek Chalupa
~ Redaktor
+1
Super člen
27. 3. 2018   #19
-
0
-
Nahlásit jako SPAM
IP: 89.177.51.–
TomyB
~ Anonymní uživatel
57 příspěvků
27. 3. 2018   #20
-
0
-

#18 Radek Chalupa
Tak jsem to předělal podle to tvého kódu a výsledek je stále stejný, asi to bude tím, že je to WinCE a možná se to chová trošku jinak.

Napadlo mě. Ono to bliknutí způsobí ten moment mezi vykreslením pozadi buttonu a vykreslením textu.

Nelze tyto dve věci nějak spojit dohromady tedy vrazit text na bitmapu a tu pak zobrazit, nebo nejdriv načíst do paměti bitmapu pozadi a pak vepsat text a pak to zobrazit na tlacitko?

Nahlásit jako SPAM
IP: 94.113.172.–
TomyB
~ Anonymní uživatel
57 příspěvků
27. 3. 2018   #21
-
0
-

#19 Radek Chalupa
Tohle mi ve W10 běží hezky, žádný problém.

Nahlásit jako SPAM
IP: 94.113.172.–
Radek Chalupa
~ Redaktor
+1
Super člen
27. 3. 2018   #22
-
0
-

#20 TomyB
jj, to jsem si neuvědomil že to jsou winCE.

Nicméně můžeš zkusit kompletní buffering požadovaného obsahu okna do paměťové bitmapy a tu pak kreslit na wm_paint a wm_erasegkgnd zadržet. Viz. např zde: https://www.radekchalupa.cz/clanky/buffering-v-gdi/

Nahlásit jako SPAM
IP: 89.177.51.–
TomyB
~ Anonymní uživatel
57 příspěvků
27. 3. 2018   #23
-
0
-

#22 Radek Chalupa
Tak blikání vyřešeno, ale neuvolňuje se mi paměť, když kliknu asi 10x na button, ta app spadne z důvodu nedostatku paměti.

 Tohle mam ve WM_DRAWITEM

	RECT Rec;
	GetClientRect(lpDIS->hwndItem, &Rec);

	g_hdcMem = CreateCompatibleDC(lpDIS->hDC);
	HBITMAP g_hBitmapMem = CreateCompatibleBitmap(lpDIS->hDC, Rec.right, Rec.bottom);

	HGDIOBJ hOld = SelectObject(g_hdcMem, g_hBitmapMem);
	
	FillRect(g_hdcMem, &Rec, hbPozadi);
	SetBkMode(g_hdcMem, TRANSPARENT);
	SetTextColor(g_hdcMem, 0x00AFFFFF);
	DrawText(g_hdcMem, TEXT("TEST BUTTON"), -1, &Rec, DT_CENTER);

	BitBlt(lpDIS->hDC, 0, 0, Rec.right, Rec.bottom, g_hdcMem, 0, 0, SRCCOPY);

	SelectObject(g_hdcMem, hOld);
	DeleteObject(g_hBitmapMem);
	DeleteDC(g_hdcMem);
	ReleaseDC(lpDIS->hwndItem, lpDIS->hDC);
Nahlásit jako SPAM
IP: 94.113.172.–
TomyB
~ Anonymní uživatel
57 příspěvků
27. 3. 2018   #24
-
0
-

#21 TomyB
BINGOO

jsem zapoměl deletovat jeste HBRUSH

Takže teď to funguje perfektně :-)

Moc díky za trpělivost a za hlavně pomoc

Nahlásit jako SPAM
IP: 94.113.172.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 64 hostů

Podobná vlákna

ImagingFactory WinCE — založil TomyB

Práce s textem — založil bohetik

Práce s textem — založil Janule

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý