Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!
Werbeanzeige
Anonymous
unregistriert
![]() |
C-/C++-Quelltext |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
#ifndef _DISPLAY_BITMAP_H #define _DISPLAY_BITMAP_H #include <iostream> // Include the standard C++ file #include <windows.h> // We need to include windows.h using namespace std; // Include the standard namespace typedef struct _BMP { BITMAPFILEHEADER *bmFileHeader; BITMAPINFO *bmFileInfo; HBITMAP hBitmap; HANDLE hFilePointer; HANDLE hFileMapping; PUCHAR BeginOfFile; PUCHAR BeginOfImage; char szFileName[48]; }BMP; // The function prototype for our WndProc (The function that handles all the windows messages) LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); // This loads a bitmap and assigns the info to the BMP structure bool LoadABitmap(BMP *Bmp, char *szFile); // This displays the bitmap to the screen at a X and a Y location void DisplayBitmap(HDC hdc, BMP *bitmap, int x, int y); #endif |
![]() |
C-/C++-Quelltext |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
#include "DisplayBitmap.h" // Include our own header file which holds all the include and structure/function prototype information int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) // Anyway, so here is our "main()" for windows. Must Have this for a windows app. { HWND hwnd; // Create the handle to the window. MSG msg; // Create the variable to hold the window messages WNDCLASSEX wndclass; // Create the structure that holds the attributes of the window wndclass.cbSize = sizeof (wndclass); // Set the size of the class (required) wndclass.style = CS_HREDRAW | CS_VREDRAW; // Set the style of the window to redraw horizontally and vertically. wndclass.lpfnWndProc = WndProc; // Assign the callback function to our window. wndclass.cbClsExtra = 0; // We don't need any extra bytes wndclass.cbWndExtra = 0; // We don't need any extras wndclass.hInstance = hInstance; // Assign the hInstance passed from the OS to the window wndclass.hIcon = LoadIcon (NULL, IDI_WINLOGO); // Set the windows logo Icon wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); // Set the default arrow to the window // Set the background to white wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); wndclass.lpszMenuName = NULL; // Set the menu to NULL wndclass.lpszClassName = "Window Class"; // Set the name of our windows class wndclass.hIconSm = LoadIcon (NULL, IDI_WINLOGO); // Assign the small icon to the windows logo RegisterClassEx (&wndclass); // Register the window class with the operating system // Now, we actually create the window hwnd = CreateWindow ("Window Class", // window class name "Bitmap Background", // window's Title WS_OVERLAPPEDWINDOW, // window style CW_USEDEFAULT, // initial x position CW_USEDEFAULT, // initial y position CW_USEDEFAULT, // initial x size CW_USEDEFAULT, // initial y size NULL, // This is the parent window handle. NULL, // This is the window menu handle hInstance, // This is the programs instance handle. NULL); // We don't want to pass any extra data in, so NULL ShowWindow (hwnd, iCmdShow); // This shows our window. UpdateWindow (hwnd); // This pretty much paints our window to the screen. while (GetMessage (&msg, NULL, 0, 0)) // Here is our main loop. { TranslateMessage (&msg); // This Translates messages so windows understands them. DispatchMessage (&msg); // This sends the messages to the WndProc(). } UnregisterClass("Window Class",hInstance); // Unregister the window class with the operating system return msg.wParam ; // Quit the program } // Here is the WndProc that handles all the messages LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { HDC hdc; // Create a handle to the device context (We need this for every graphic operation) static BMP Bmp; // Create our structure that will hold the bitmap info. // We make it static because we don't want it to change. // A static variable is initialized, but is not freed (erased) when the function ends. // We could just make it global by putting outside of any function, but globals are dangerous. // If we didn't have this static it would read in the bitmap, and then when this function finished, // It would erase everything and then it wouldn't have any info on the bitmap. Try deleting the static to see what I mean. PAINTSTRUCT ps; RECT windowRect; static int x=0, y=0; switch (iMsg) // Check which message was passed in { case WM_CREATE: // Here we load our bitmap (This happens only ONCE). "Bitmap.bmp" is our bitmap name. if(!LoadABitmap(&Bmp, "Bitmap.bmp")) // We pass in the address to the BMP structure we created. This will fill in the data. { // Display a error message if we can't find the bitmap. MessageBox(hwnd, "Can't find Bitmap.bmp! (Make sure it's in the same directory as the .cpp file)", "Error!", MB_OK); exit(0); // Quit the program if the bitmap is not found! } // The bitmap must be in the same directory as your .cpp file, or .exe if you don't have the code. break; // LoadABitmap() returns a FALSE if we can't find the bitmap. case WM_MOUSEMOVE: x = LOWORD(lParam); // Get the x position from the LOW bits of the lParam y = HIWORD(lParam); // Get the y position from the HIGH bits of the lParam // Once again, the LOWORD and HIWORD is a way to extract half of the total bits. // Reviewing, bits are 1's and 0's. So, 1101 is 4 bits. 11000110 8 bits (also 1 byte). // The HIWORD and LOWORD macro's just access half of those bits. For instance: // If we have, "1101" , the HI would be "11" and the LO would be "01". It just cuts it in half. // A DWORD is 32-bits, so the low 16 bits hold the x position, and the top 16 bits hold the y position. GetClientRect(hwnd, &windowRect); // Get the rectangle of the window InvalidateRect(hwnd, &windowRect, TRUE); // This function clears the window's rectangle. It essentially forces a WM_PAINT message. break; case WM_PAINT: // Here is where everything is painted to the screen hdc = BeginPaint(hwnd, &ps); // Get a DC DisplayBitmap(hdc, &Bmp, x, y); // Display the bitmap under the cursor // See if you can try and use some math to center the bitmap on the cursor. EndPaint(hwnd, &ps); // Free the paint structure break; case WM_DESTROY: // This message is sent when the user closes the window. PostQuitMessage(0); // Post the QUIT message to the window (0 = WM_QUIT) break; } return DefWindowProc (hwnd, iMsg, wParam, lParam); // Process the default messages } bool LoadABitmap(BMP *Bmp, char *szFile) { memset(Bmp,0, sizeof(BMP)); // This sets the structure to 0. memset means "memory set()" // The sizeof() function gets the size in bytes of the structure BMP // The rest of this stuff is reading in the bitmap. Each bitmap has // A header before the image in the file that holds the information about the type of bitmap. // I won't go into to much detail about it, because you can get the information off the internet. // Essentially, a bitmap is stored with a header first, then the bitmap information (size, pixels info, etc..) // Then the image bits. The image bits are the actual pixels. // This opens the file and assigns a file pointer to our structure. Just like fopen(), but this is better. Bmp->hFilePointer = CreateFile(szFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN, NULL); // This checks if the file pointer is valid, if we didn't find the file, return FALSE , or 0. if(Bmp->hFilePointer == INVALID_HANDLE_VALUE) return(0); // This function returns a handle to the file. We can choose to view ALL of the file, or parts of it. // Later, in animation we will utilize the option to only view parts of the image with this function. Bmp->hFileMapping = CreateFileMapping(Bmp->hFilePointer, NULL, PAGE_READONLY, 0, 0, NULL); // Here we get a handle to the beginning of the file, so we know where to start reading in the header information. Bmp->BeginOfFile = (PUCHAR)MapViewOfFile(Bmp->hFileMapping, FILE_MAP_READ, 0, 0, 0); // Now we cast the handle to the beginning of the file as a bitmap header structure. Now we have the file header stored. Bmp->bmFileHeader = (BITMAPFILEHEADER*)Bmp->BeginOfFile; // Now we add the size of the header from the beginning to move past that part in the file. Bmp->BeginOfFile = sizeof(BITMAPFILEHEADER) + Bmp->BeginOfFile; Bmp->bmFileInfo = (BITMAPINFO*)Bmp->BeginOfFile; // Now we are at the part of the file that holds the actual bitmap information. // This stores the beginning of the image bits. Some funky math on my part for more precision. Bmp->BeginOfImage = (PUCHAR) Bmp->BeginOfFile + Bmp->bmFileHeader->bfOffBits-sizeof(PUCHAR)*3-2; return(1); // Return a success!! } // End of LoadABitmap() void DisplayBitmap(HDC hdc, BMP *bitmap, int x, int y) // This displays the bitmap! Passed in our hdc, the bitmap structure, and the position to display it (x, y) { HDC hdc2; // Create the DIB Section bitmap->hBitmap = CreateDIBSection(NULL, bitmap->bmFileInfo, DIB_RGB_COLORS,NULL, NULL,0); // Set the bits into the hdc SetDIBits(hdc, bitmap->hBitmap, 0, bitmap->bmFileInfo->bmiHeader.biHeight, bitmap->BeginOfImage, bitmap->bmFileInfo, DIB_RGB_COLORS); // Get a patterm handle hdc2 = CreateCompatibleDC(hdc); // Create a pseudo backbuffer SelectObject(hdc2, bitmap->hBitmap); // Put the bitmap into the backbuffer // Blit the backbuffer to the screen BitBlt(hdc, x, y, x + bitmap->bmFileInfo->bmiHeader.biWidth, y + bitmap->bmFileInfo->bmiHeader.biHeight, hdc2, 0, 0, SRCCOPY); DeleteDC(hdc); // Delete the first hdc (Frees the memory) DeleteDC(hdc2); // Delete the second hdc (Frees the memory) DeleteObject(bitmap->hBitmap); // Delete the handle to the bitmap (Frees the memory) } |