Visualizzazione dei risultati da 1 a 6 su 6
  1. #1
    Utente di HTML.it
    Registrato dal
    Oct 2007
    Messaggi
    216

    [C++ API Win32] problema avvio programma

    Ciao, ho un programma che dovrebbe disegnare un righello sull'area client,
    ma non riesco a capire perchè quando lo mando in esecuzione la finestra non
    si apre. Potete aiutarmi? Grazie.
    Questo è il codice:
    codice:
    #include <windows.h>
    #include "resource.h"
    
    extern void RoutineCrea(HWND);
    extern void RoutineMostra(HWND, HDC, int, int);
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    
    HANDLE hInst;
    
    extern TCHAR szClasse[];
    extern TCHAR szTitolo[];
    
    int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
    	{
    		HWND hwnd;
    		MSG msg;
    		WNDCLASS wndclass;
    
    		hInst = hInstance;
    
    		wndclass.style = CS_HREDRAW | CS_VREDRAW;
    		wndclass.lpfnWndProc = WndProc;
    		wndclass.cbClsExtra = 0;
    		wndclass.cbWndExtra = 0;
    		wndclass.hInstance = hInstance;
    		wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    		wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    		wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //Imposta lo sfondo con un brush bianco
    		wndclass.lpszMenuName = MAKEINTRESOURCE(ID_MENU);
    		wndclass.lpszClassName = szClasse;
    
    		RegisterClass(&wndclass); //registrazione della classe
    
    		hwnd = CreateWindow(szClasse, //nome della classe window
    							szTitolo, //titolo della finestra(barra del titolo)
    							WS_OVERLAPPEDWINDOW, //stile window
    							20, //posizione x iniziale
    							30, //posizione y iniziale
    							CW_USEDEFAULT, //dimensione x iniziale(lunghezza)
    							CW_USEDEFAULT, //dimensione y iniziale(altezza)
    							NULL, //handle alla finestra genitore
    							NULL, //handle al menù della finestra
    							hInstance, //handle all'istanza del programma
    							NULL); //parametri di creazione
    
    		ShowWindow(hwnd, iCmdShow); //disegna la finestra sullo schermo, con le impostazioni iniziali date dall'utente
    
    		UpdateWindow(hwnd); //disegna (aggiorna) l'area client della finestra
    
    		//ciclo dei messaggi
    		while (GetMessage(&msg, NULL,  0, 0)) //recupera un messaggio dalla coda (restituisce FALSE (0) solo per WM_QUIT)
    			{
    				TranslateMessage(&msg);	//opera alcune modifiche al messaggio a seconda della tastiera
    				DispatchMessage(&msg);	//invia il messaggio alla window procedure appropriata
    			}
    		return  msg.wParam;
    	}
    
    BOOL RoutineStampa(HWND hwnd)
    {
    	static DOCINFO di;
    	static PRINTDLG printDlg = { sizeof(PRINTDLG) };
    	static TCHAR szMessaggio[32];
    	BOOL bSuccesso = FALSE;
    	HDC hdcStampa;
    	int cxPagina, cyPagina;
    
    	printDlg.Flags = PD_RETURNDC | PD_NOPAGENUMS | PD_NOSELECTION;
    
    	if(!PrintDlg(&printDlg))
    		return TRUE;
    
    	hdcStampa = printDlg.hDC;
    
    	if(NULL == hdcStampa)
    		return FALSE;
    
    	cxPagina = GetDeviceCaps(hdcStampa, HORZRES);
    	cyPagina = GetDeviceCaps(hdcStampa, VERTRES);
    
    	lstrcpy(szMessaggio, szClasse);
    	lstrcat(szMessaggio, TEXT(": Stampa"));
    
    	di.cbSize = sizeof(DOCINFO);
    	di.lpszDocName = szMessaggio;
    
    	if(StartDoc(hdcStampa, &di) > 0)
    	{
    		if(StartPage(hdcStampa) > 0)
    		{
    			RoutineMostra(hwnd, hdcStampa, cxPagina, cyPagina);
    
    			if(EndPage(hdcStampa) > 0)
    			{
    				EndDoc(hdcStampa);
    				bSuccesso = TRUE;
    			}
    		}
    	}
    
    	DeleteDC(hdcStampa);
    
    	return bSuccesso;
    }
    
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	BOOL bSuccesso;
    	static int cxClient, cyClient;
    	HDC hdc;
    	PAINTSTRUCT ps;
    
    	switch(message)
    	{
    
    		case WM_CREATE:
    			RoutineCrea(hwnd);
    			return 0;
    		case WM_COMMAND:
    			switch(wParam)
    			{
    				case IDM_FILE_STAMPA:
    					SetCursor(LoadCursor(NULL, IDC_WAIT));
    					ShowCursor(TRUE);
    
    					bSuccesso = RoutineStampa(hwnd);
    
    					ShowCursor(FALSE);
    					SetCursor(LoadCursor(NULL, IDC_ARROW));
    
    					if(!bSuccesso)
    						MessageBox(hwnd, TEXT("Errore riscontrato durante la stampa"), szClasse, MB_ICONASTERISK | MB_OK);
    
    					return 0;
    
    				case IDM_FILE_ESCI:
    					SendMessage(hwnd, WM_CLOSE, 0, 0);
    					return 0;
    
    				case IDM_AIUTO_INFORMAZIONI_SU:
    					MessageBox(hwnd, TEXT("MetafileAvanzatoRighello\nCopyright (c) Minnozzi Corrado, 2010"), szClasse, MB_ICONINFORMATION | MB_OK);
    					return 0;
    			}
    			break;
    
    		case WM_SIZE:
    			cxClient = LOWORD(lParam);
    			cyClient = HIWORD(lParam);
    			return 0;
    
    		case WM_PAINT:
    			hdc = BeginPaint(hwnd, &ps);
    
    			RoutineMostra(hwnd, hdc, cxClient, cyClient);
    
    			EndPaint(hwnd, &ps);
    			return 0;
    
    		case WM_DESTROY:
    			PostQuitMessage(0);
    			return 0;
    	}
    	DefWindowProc(hwnd, message, wParam, lParam);
    }
    Questo invece è il file dove sono definite le funzioni:
    codice:
    #include <windows.h>
    
    TCHAR szClasse[] = TEXT("MetafileAvanzatoRighello");
    TCHAR szTitolo[] = TEXT("Disegna un righello con un metafile avanzato");
    
    void DisegnaRighello(HDC hdc, int cx, int cy)
    {
    	int iAdattamento, i, iAltezza;
    	LOGFONT lf;
    	TCHAR ch;
    
    	iAdattamento = GetVersion() & 0x80000000 ? 0 : 1;
    
    	SelectObject(hdc, CreatePen(PS_SOLID, cx / 72 / 6, 0));
    
    	Rectangle(hdc, iAdattamento, iAdattamento, cx + iAdattamento + 1, cy + iAdattamento + 1);
    
    	for(i = 1; 1 < 96; i++)
    	{
    		if(i % 16 == 0)
    			iAltezza = cy / 2;
    		else if(i % 8 == 0)
    			iAltezza = cy / 3;
    		else if(i % 4 == 0)
    			iAltezza = cy / 5;
    		else if(i % 2 == 0)
    			iAltezza = cy / 8;
    		else
    			iAltezza = cy / 12;
    
    		MoveToEx(hdc, i * cx / 96, cy, NULL);
    		LineTo(hdc, i * cx / 96, cy - iAltezza);
    	}
    
    	FillMemory(&lf, sizeof(lf), 0);
    	lf.lfHeight = cy / 2;
    	lstrcpy(lf.lfFaceName, TEXT("Times New Roman"));
    
    	SelectObject(hdc, CreateFontIndirect(&lf));
    	SetTextAlign(hdc, TA_BOTTOM | TA_CENTER);
    	SetBkMode(hdc, TRANSPARENT);
    
    	for(i = 1; i <= 5; i++)
    	{
    		ch = (TCHAR)(i + '0');
    		TextOut(hdc, i * cx / 6, cy / 2, &ch, 1);
    	}
    
    	DeleteObject(SelectObject(hdc, GetStockObject(SYSTEM_FONT)));
    	DeleteObject(SelectObject(hdc, GetStockObject(BLACK_PEN)));
    }
    
    void RoutineCrea(HWND hwnd)
    {
    	HDC hdcEMF;
    	HENHMETAFILE hemf;
    	int cxMm, cyMm, cxPixel, cyPixel, xDpi, yDpi;
    
    	hdcEMF = CreateEnhMetaFile(NULL, TEXT("MetafileAvanzatoRighello.emf"), NULL, TEXT("MetafileAvanzatoRighello\0Disegnare un righello con Metafile Avanzato"));
    
    	if(hdcEMF == NULL)
    		return;
    
    	cxMm = GetDeviceCaps(hdcEMF, HORZSIZE);
    	cyMm = GetDeviceCaps(hdcEMF, VERTSIZE);
    	cxPixel = GetDeviceCaps(hdcEMF, HORZRES);
    	cyPixel = GetDeviceCaps(hdcEMF, VERTRES);
    
    	xDpi = cxPixel * 254 / cxMm / 10;
    	yDpi = cyPixel * 254 / cyMm / 10;
    
    	DisegnaRighello(hdcEMF, 6 * xDpi, yDpi);
    
    	hemf = CloseEnhMetaFile(hdcEMF);
    	DeleteEnhMetaFile(hemf);
    }
    
    void RoutineMostra(HWND hwnd, HDC hdc, int cxArea, int cyArea)
    {
    	ENHMETAHEADER emh;
    	HENHMETAFILE hemf;
    	int cxImmagine, cyImmagine;
    	RECT rect;
    
    	hemf = GetEnhMetaFile(TEXT("MetafileAvanzatoRighello.emf"));
    
    	GetEnhMetaFileHeader(hemf, sizeof(emh), &emh); 
    	 
    	cxImmagine = emh.rclBounds.right - emh.rclBounds.left;
    	cyImmagine = emh.rclBounds.bottom - emh.rclBounds.top;
    
    	rect.left = (cxArea - cxImmagine) / 2;
    	rect.right = (cxArea + cxImmagine) / 2;
    	rect.top = (cyArea - cyImmagine) / 2;
    	rect.bottom = (cyArea + cyImmagine) / 2;
    
    	PlayEnhMetaFile(hdc, hemf, &rect);
    
    	DeleteEnhMetaFile(hemf);
    }

  2. #2
    Per restringere il campo nella ricerca di errori di questo genere dovresti in primo luogo aggiungere controlli su tutti i valori restituiti dalle API che possono fallire.
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    Utente di HTML.it L'avatar di linoma
    Registrato dal
    Mar 2010
    Messaggi
    1,346
    Potrebbero essere le risorse, tipo il menu della classe.
    Per gli Spartani e Sparta usa spartan Il mio github

  4. #4
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Tanto per cominciare, deve essere

    codice:
    return(DefWindowProc(hwnd, message, wParam, lParam));
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  5. #5
    Utente di HTML.it
    Registrato dal
    Oct 2007
    Messaggi
    216
    Si l'errore del return dopo l'avevo notato anch'io, ma ancora non va.
    Se vado su Gestione attività, il processo del programma è presente.

  6. #6
    Hai fatto come ti ho detto?
    Amaro C++, il gusto pieno dell'undefined behavior.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.