Wyświetlanie czystego zdjęcia na pulpicie (bez okna)

0

Witam. Chciałbym stworzyć program, który wyświetli mi zdjęcie i napisy pod zdjęciem bez ramki/okienka. Szukałem dużo po internecie i ciągle są poradniki z zdjęciem w oknie

W załączniku dodałem przykładowe zdjęcia.

c1.png - jest to mój oczekiwany efekt
c2.png - czego nie chcę

Z góry dziękuję za każdą pomoc

0

Ustawiasz sobie styl okna na okno bez obramowania, a potem na jego całej powierzchni wyświetlasz zdjęcie/grafikę.

Jeśli chcesz dodać napis pod oknem/zdjęciem (a nie nałożyć na nie) to musisz pobawić się regionami - https://docs.microsoft.com/pl-pl/windows/win32/api/winuser/nf-winuser-setwindowrgn

1

Ramka okna wygląda jak na MacOS (albo jakiś Linux).
Autor pytania oczywiście zapomniał wspomnieć o jaką platformę chodzi oraz z jakich bibliotek korzysta.

0

Tak to jest przykładowe zdj. Korzystam z windowsa

Mam coś takiego

#include <Windows.h>

HDC         imageDC;        
HBITMAP     imageBmp;       
HBITMAP     imageBmpOld;    

const int   screenSize_X = 640;
const int   screenSize_Y = 480;

void loadImage(const char* pathname)
{
	imageDC = CreateCompatibleDC(NULL);     

	imageBmp = (HBITMAP)LoadImageA(         
		NULL,                           
		pathname,                       
		IMAGE_BITMAP,                   
		0, 0,                            
		LR_DEFAULTSIZE | LR_LOADFROMFILE
	);

	imageBmpOld = (HBITMAP)SelectObject(imageDC, imageBmp);
}

void cleanUpImage()
{
	SelectObject(imageDC, imageBmpOld);      
	DeleteObject(imageBmp);                 
	DeleteDC(imageDC);                      
}

void drawImage(HDC screen)
{
	BitBlt(
		screen,         
		0, 0,            
		screenSize_X,   
		screenSize_Y,   
		imageDC,       
		0, 0,            
		SRCCOPY         
	);
}

LRESULT CALLBACK wndProc(HWND wnd, UINT msg, WPARAM w, LPARAM l)
{
	// what kind of message is this?
	switch (msg)
	{
	case WM_PAINT:
	{
		PAINTSTRUCT ps;
		HDC screen = BeginPaint(wnd, &ps);   
		drawImage(screen);                  
		EndPaint(wnd, &ps);                  
	}break;

	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	}
	return DefWindowProc(wnd, msg, w, l);
}

HWND createWindow(HINSTANCE inst)
{
	WNDCLASSEX wc = { 0 };        
	wc.cbSize = sizeof(WNDCLASSEX);     
	wc.hCursor = LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW));        
	wc.hInstance = inst;                   
	wc.lpfnWndProc = wndProc;                
	wc.lpszClassName = TEXT("DisplayImage");   

	RegisterClassEx(&wc);           

	int style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU;   

	RECT rc = { 0,0,screenSize_X,screenSize_Y };      
	AdjustWindowRect(&rc, style, FALSE);               

	return CreateWindow(            
		TEXT("DisplayImage"),       
		TEXT("Display an Image"),   
		style | WS_VISIBLE,         
		100, 100,                    
		rc.right - rc.left,         
		rc.bottom - rc.top,         
		NULL, NULL,                  
		inst,                       
		NULL);                      

}

int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmd, int show)
{
	loadImage("c1.bmp");

	HWND wnd = createWindow(inst);

	MSG msg;
	while (GetMessage(&msg, wnd, 0, 0)) 
	{
		TranslateMessage(&msg);     
		DispatchMessage(&msg);      
	}
	cleanUpImage();
}

Tylko, że wyświetla błąd i nw jak to naprawić

Błąd	C2001	 w stałej występuje symbol przejścia do następnego wiersza
Błąd	C2146	 błąd składniowy: brakuje „)” przed identyfikatorem „HWND”
0

Znalazłem coś takiego, leczy wyświetla puste okno :/

#include <windows.h>
#include <tchar.h>

HBITMAP hBitmap;
HDC localDC;
HBITMAP hOld;
BITMAP qB;
HDC hDC;                                             // Handle (virtual memory pointer) to drawing characteristics

LRESULT CALLBACK fnWndProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam) {
	switch (msg) {
	case WM_CREATE: {
		//MessageBox(hwnd,_T("Window Procedure Received WM_CREATE Message!"),_T("Message Report!"),MB_OK);
		return 0;
	}
	case WM_LBUTTONDOWN: {
		//MessageBox(hwnd,_T("Window Procedure Received WM_LBUTTONDOWN Message!"),_T("Message Report!"),MB_OK);
		return 0;
	}

	case WM_PAINT: {                  //At program start up the whole window is invalid so must be drawn.
		//TCHAR tmpText[]=_T("TempText");
		PAINTSTRUCT ps;
		hDC = BeginPaint(hwnd, &ps);
		BOOL qRetBlit = ::BitBlt(hDC, 0, 0, qB.bmWidth, qB.bmHeight, localDC, 0, 0, SRCCOPY);
		// Draw text on top of the image
		//int iBkMode=SetBkMode(hDC,TRANSPARENT);                   // Save Background Mode characteristic of drawing context
		//TextOut(hDC,40,20,tmpText,(int)_tcslen(tmpText));     // Draw Text
		//SetBkMode(hDC,iBkMode);                                       // Return Drawing Context To Original State
		EndPaint(hwnd, &ps);
		return 0;
	}
	case WM_DESTROY: {
		::SelectObject(localDC, hOld);
		::DeleteDC(localDC);
		::DeleteObject(hBitmap);
		PostQuitMessage(0);
		return 0;
	}
	}
	return (DefWindowProc(hwnd, msg, wParam, lParam));
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int iShow) {
	TCHAR szClassName[] = _T("Name");
	WNDCLASSEX wc;
	MSG messages;
	HWND hWnd;

	wc.lpszClassName = szClassName;                     //Important Field!  Character string identifying window class
	wc.lpfnWndProc = fnWndProc;                       //Important Field!  Function Pointer.  Address of Window Procedure
	wc.cbSize = sizeof(WNDCLASSEX);             //Those top two fields I just listed are very important.  The
	wc.style = 0;                               //others are of course necessary too, but fully understanding all
	wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);  //the implications of the .szClassName and .lpfnWndProc fields will
	wc.hInstance = hInstance;                       //go a long way to helping you understand Win32 coding. The
	wc.hIconSm = 0;                               //.hBrushBackground field will be the color of the Window's
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);      //background.  The .cbWndExtra field is very useful as it allows
	wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;         //you to associate object (Window) data to the instantiated Window's
	wc.cbWndExtra = 0;                               //internal structure, i.e., accomodate member data.
	wc.cbClsExtra = 0;
	wc.lpszMenuName = NULL;
	RegisterClassEx(&wc);
	hBitmap = (HBITMAP)::LoadImage(NULL, (LPCTSTR)"c1.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
	GetObject(reinterpret_cast<HGDIOBJ>(hBitmap), sizeof(BITMAP), reinterpret_cast<LPVOID>(&qB));
	localDC = ::CreateCompatibleDC(hDC);
	hOld = (HBITMAP)::SelectObject(localDC, hBitmap);

	hWnd = CreateWindowEx(0, szClassName, szClassName, WS_OVERLAPPEDWINDOW, 0, 0, qB.bmWidth, qB.bmHeight, HWND_DESKTOP, 0, hInstance, 0);
	ShowWindow(hWnd, iShow);
	while (GetMessage(&messages, NULL, 0, 0)) {
		TranslateMessage(&messages);
		DispatchMessage(&messages);
	}
	return (int)messages.wParam;
}

Jaka może być tego przyczyna ?

0

Takie pytanie, może z czapy, ale warto zapytać ;)
Czy masz w katalogu z plikiem .exe plik z grafiką, którą chcesz załadować oraz czy ten plik nazywa się c1.bmp?

0

Tak. Mam plik c1.bmp w katalogu projektu z Visuala C++ Gdy robiłem zapis danych to plik z danymi pojawił się w tej samej lokalizacji, więc lokalizacja jest na 100% dobra. Pliku .exe nie mam, gdyż odpalałem projekt przez Visuala

1

VS nie używam za często, więc moja rada może być nietrafiona, ale czy Studio zapisuje exe w katalogu projektu, czy w jakimś podfolderze typu build albo podobnym? Bo być może to jest przyczyną. Możesz spróbować zrobić trzy rzeczy:
1) zmień string podany w kodzie z c1.bmp na sdtrsggsdf.bmp i zobacz, czy aplikacja zachowa się jakoś inaczej, wyskoczy jakiś błąd itp.
**2) ** wygeneruj exe, wrzuć do jednego folderu z plikiem bmp i odpal
3) podaj w miejscu, w którym wczytujesz obrazek ścieżkę bezwzględną - coś w stylu c:\obrazek.bmp

2

(LPCTSTR)"c1.bmp"

Jeśli już, to TEXT("c1.bmp")

0
0x666 napisał(a):

(LPCTSTR)"c1.bmp"

Jeśli już, to TEXT("c1.bmp")

Faktycznie. Pomogło wielkie dzięki ;)

A jak mogę się pozbyć ramki/okna z tego zdjęcia ?

1

Kombinuj ze stylami okna. Może WS_POPUP...

0

Poradziłem sobie. Użyłem SetWindowLong oraz ShowScrollBar Dzięki za pomoc

Poniżej daję kod gdyby ktoś potrzebował.

#include <windows.h>
#include <tchar.h>

HBITMAP hBitmap;
HDC localDC;
HBITMAP hOld;
BITMAP qB;
HDC hDC;                                             // Handle (virtual memory pointer) to drawing characteristics

LRESULT CALLBACK fnWndProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam) {
	switch (msg) {
	case WM_CREATE: {
		//MessageBox(hwnd,_T("Window Procedure Received WM_CREATE Message!"),_T("Message Report!"),MB_OK);
		return 0;
	}
	case WM_LBUTTONDOWN: {
		//MessageBox(hwnd,_T("Window Procedure Received WM_LBUTTONDOWN Message!"),_T("Message Report!"),MB_OK);
		return 0;
	}

	case WM_PAINT: {                  //At program start up the whole window is invalid so must be drawn.
		//TCHAR tmpText[]=_T("TempText");
		PAINTSTRUCT ps;
		hDC = BeginPaint(hwnd, &ps);
		BOOL qRetBlit = ::BitBlt(hDC, 0, 0, qB.bmWidth, qB.bmHeight, localDC, 0, 0, SRCCOPY);
		// Draw text on top of the image
		//int iBkMode=SetBkMode(hDC,TRANSPARENT);                   // Save Background Mode characteristic of drawing context
		//TextOut(hDC,40,20,tmpText,(int)_tcslen(tmpText));     // Draw Text
		//SetBkMode(hDC,iBkMode);                                       // Return Drawing Context To Original State
		EndPaint(hwnd, &ps);
		return 0;
	}
	case WM_DESTROY: {
		::SelectObject(localDC, hOld);
		::DeleteDC(localDC);
		::DeleteObject(hBitmap);
		PostQuitMessage(0);
		return 0;
	}
	}
	return (DefWindowProc(hwnd, msg, wParam, lParam));
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int iShow) {
	TCHAR szClassName[] = _T("Name");
	WNDCLASSEX wc;
	MSG messages;
	HWND hWnd;

	wc.lpszClassName = szClassName;                     //Important Field!  Character string identifying window class
	wc.lpfnWndProc = fnWndProc;                       //Important Field!  Function Pointer.  Address of Window Procedure
	wc.cbSize = sizeof(WNDCLASSEX);             //Those top two fields I just listed are very important.  The
	wc.style = 0;                               //others are of course necessary too, but fully understanding all
	wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);  //the implications of the .szClassName and .lpfnWndProc fields will
	wc.hInstance = hInstance;                       //go a long way to helping you understand Win32 coding. The
	wc.hIconSm = 0;                               //.hBrushBackground field will be the color of the Window's
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);      //background.  The .cbWndExtra field is very useful as it allows
	wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;         //you to associate object (Window) data to the instantiated Window's
	wc.cbWndExtra = 0;                               //internal structure, i.e., accomodate member data.
	wc.cbClsExtra = 0;
	wc.lpszMenuName = NULL;
	RegisterClassEx(&wc);
	hBitmap = (HBITMAP)::LoadImage(NULL, TEXT("c1.bmp"), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
	GetObject(reinterpret_cast<HGDIOBJ>(hBitmap), sizeof(BITMAP), reinterpret_cast<LPVOID>(&qB));
	localDC = ::CreateCompatibleDC(hDC);
	hOld = (HBITMAP)::SelectObject(localDC, hBitmap);

	hWnd = CreateWindowEx(0, szClassName, szClassName, WS_OVERLAPPEDWINDOW, 0, 0, qB.bmWidth, qB.bmHeight, HWND_DESKTOP, 0, hInstance, 0);

	LONG lStyle = GetWindowLong(hWnd, GWL_STYLE);

	lStyle &= ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU);

	SetWindowLong(hWnd, GWL_STYLE, lStyle);
	ShowScrollBar(hWnd, SB_VERT, FALSE);
	ShowWindow(hWnd, iShow);

	while (GetMessage(&messages, NULL, 0, 0)) {
		TranslateMessage(&messages);
		DispatchMessage(&messages);
	}
	return (int)messages.wParam;
}

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