Funkcja tworzaca okienko nie działa

0

Witam. W załączniku mam folder z programem w którym próbuje zrobić własną kontrolkę. Niestety funkcja CreatePrzycisk() nie działa poprawnie i nie wiem dlaczego. Pomożecie?

1

Windows 8: The WS_EX_LAYERED style is supported for top-level windows and child windows. Previous Windows versions support WS_EX_LAYERED only for top-level windows.

Czyli: Okno dziecko obsługuje ten styl od windows 8 w górę.
Jak poprawić? AlphaBlend obsługuje kanał alpha przy obrazku ;)

*okno = CreateWindowEx(WS_EX_LAYERED, "PRZYCISK", NULL, WS_CHILD | WS_VISIBLE, x, y, wsk->weight, wsk->height, hwnd, (HMENU)ID, *hInstance, NULL );

zamień na:

*okno = CreateWindowEx(NULL, "PRZYCISK", NULL, WS_CHILD | WS_VISIBLE, x, y, wsk->weight, wsk->height, hwnd, (HMENU)ID, *hInstance, NULL );

W odpowiedzi na WM_PAINT zrób:

PAINTSTRUCT ps;
HDC			PaintDC = BeginPaint( m_hHandle, &ps );

if ( PaintDC )
{
	//Create DC compatible to application screen
	HDC MemoryDC = CreateCompatibleDC( NULL );
	if ( MemoryDC )
	{
		HBITMAP hbmOld   = (HBITMAP)SelectObject( MemoryDC, wsk->hBitmap );
		if ( hbmOld )
		{
			BITMAP bm;
			if ( GetObject( wsk->hBitmap, sizeof( bm ), &bm ) == sizeof( bm ) )
			{
				BLENDFUNCTION Blender;

				Blender.BlendOp				= AC_SRC_OVER;
				Blender.BlendFlags			= 0;
				Blender.SourceConstantAlpha	= 0xFF;
				Blender.AlphaFormat			= AC_SRC_ALPHA;


				AlphaBlend( PaintDC, 0, 0, bm.bmWidth, bm.bmHeight, MemoryDC, 0, 0,
							bm.bmWidth, bm.bmHeight, Blender );

				SelectObject(MemoryDC, hbmOld);
			}
		}

	}

	DeleteObject( MemoryDC );
	EndPaint( m_hHandle, &ps );
}

Podejrzewam, że nie będzie Ci się chciało ściągać żadnej biblioteczki do wczytywania obrazków obsługujących przeźroczystość, ani korzystać z WIC, więc radziłbym poczytać o funkcji TransparentBlt

0

Czyli: Okno dziecko obsługuje ten styl od windows 8 w górę.
Jak poprawić? AlphaBlend obsługuje kanał alpha przy obrazku

Faktycznie usunięcie stylu WS_EX_LAYERED rozwiązało mój problem.
Ponadto funkcja TransparentBlt okazała mi się bardzo pomocna. Wielkie dzięki i łapka w górę dla ciebie :)


Mam pytanie co do funkcji TransparentBlt(...). Wywala mi taki błąd przy wywołaniu funkcji:

C:\Users\Joanna\Desktop\LAma\odtwarzacz\PRZYCISK.h||In function 'LRESULT PrzyciskProc(HWND, UINT, WPARAM, LPARAM)':|C:\Users\Joanna\Desktop\LAma\odtwarzacz\PRZYCISK.h|90|error: 'TransparentBlt' was not declared in this scope|||=== Build finished: 1 errors, 0 warnings (0 minutes, 0 seconds) ===|WinGdi.h

Mam dodany plik nagłówkowy #include <WinGdi.h>
w linkerze: ..........\Program Files (x86)\CodeBlocks\MinGW\lib\libmsimg32.a

Według http://msdn.microsoft.com/en-us/library/windows/desktop/dd145141%28v=vs.85%29.aspx wszystko powinno działać... :<

0

Requirements
Header
WinGdi.h (include Windows.h)
Library
Msimg32.lib

0
BOOL Rejestracja();

BOOL Rejestracja(HINSTANCE hInst){
    if(!RejestrujPrzycisk(hInst))
        return false;
    return true;
}

Raz że prototyp nie odpowiada funkcji (odpowiadałby gdyby to było C, ale plik ma rozszerzenie .cpp…), a dwa że ta funkcja jest całkowicie zbędna.

wc.hbrBackground =( HBRUSH ) GetStockObject( NULL_BRUSH );

Nie daje się systemowych bruszy do RegisterClass. Można dać NULL albo coś takiego:

wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
SetWindowLong(*okno, 0, (LONG)wsk);

SetWindowLong jest deprecated bo nie działa w x64. Na przyszłość lepiej przyzwyczaić się do SetWindowLongPtr:

SetWindowLongPtr(*okno, 0, (LONG_PTR)wsk);
GetWindowLong(hwnd, 0);

jw, GetWindowLongPtr

        case WM_CREATE:{
            break;

Jakbyś dodał tutaj kod, to zauważysz że twój wskaźnik sPrzycisk *wsk będzie NULL. Dlaczego? Bo WM_CREATE jest wysyłane bezpośrednio przez CreateWindow[Ex], a SetWindowLong[Ptr] jeszcze nie było. Jak to rozwiązać? zagadka ;-)

return CallWindowProc( WindowProcedure, hwnd, mesg, wParam, lParam );

To jest jakiś dziwny hack, którego nawet nie próbuję zrozumieć.

wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

Powinno być (HBRUSH)(COLOR_BACKGROUND+1). Dokumentacja wyraźnie o tym pisze. Teraz wybierasz inny kolor niż ci się wydaje.

0

SetWindowLong jest deprecated bo nie działa w x64. Na przyszłość lepiej przyzwyczaić się do SetWindowLongPtr:

Dobrze wiedzieć - dzięki.

Jak to rozwiązać? zagadka

Ja wiem! Ja wiem! Ja wiem! Mogę powiedzieć?!

1 użytkowników online, w tym zalogowanych: 0, gości: 1