How to display raw array of pixels to the screen? - c

I am new to windows programming. I want to display the raw pixel array to the screen without using SetPixel function because it's too slow in my standards. I am using this question as my reference.
I made a small program below to fill the pixel array with random RGB values and display it to the screen. The result wasn't what I anticipated, I got the white canvas. I tried to change this line ptr++ = (b << 16) | (g << 8) | r; to ptr++ = 0x000000FF; expecting red canvas but I got the same result.
#include <stdlib.h>
#include <time.h>
#include <windows.h>
const int win_width = 500;
const int win_height = 450;
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
RECT rect;
int width, height;
COLORREF *display;
switch (msg)
{
case WM_CREATE:
srand((unsigned int) time(NULL));
GetClientRect(hWnd, &rect);
width = rect.right - rect.left;
height = rect.bottom - rect.top;
display = (COLORREF *) malloc(sizeof(COLORREF) * width * height);
COLORREF *ptr = display;
for (int y = 0; y < height; ++y)
{
for (int x = 0; x < width; ++x)
{
int r = rand() % 256;
int g = rand() % 256;
int b = rand() % 256;
*ptr++ = (b << 16) | (g << 8) | r;
}
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hDC, memDC;
HBITMAP hBmp, hOldBmp;
hDC = BeginPaint(hWnd, &ps);
memDC = CreateCompatibleDC(hDC);
hBmp = CreateBitmap(width, height, 1, 32, (void *) display);
hOldBmp = (HBITMAP) SelectObject(memDC, hBmp);
BitBlt(hDC, rect.left, rect.top, width, height, memDC, 0, 0, SRCCOPY);
SelectObject(memDC, hOldBmp);
DeleteObject(hBmp);
DeleteDC(memDC);
EndPaint(hWnd, &ps);
break;
}
case WM_CLOSE:
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
const TCHAR szClassName[] = TEXT("MyClass");
WNDCLASS wc;
HWND hWnd;
MSG msg;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = szClassName;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
if (!RegisterClass(&wc))
{
MessageBox(NULL, TEXT("Window Registration Failed!"), TEXT("Error!"),
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hWnd = CreateWindow(szClassName,
TEXT("Random Pixels"),
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, win_width, win_height,
NULL, NULL, hInstance, NULL);
if (hWnd == NULL)
{
MessageBox(NULL, TEXT("Window Creation Failed!"), TEXT("Error!"),
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
I know there's something wrong with my code inside WM_PAINT but I don't know how to fix it. I will appreciate any form of assistance. Thanks in advance.

The variable display that holds the pixel data has automatic lifetime. Its lifetime ends whenever control leaves WndProc. A consequence is, that every invocation of WndProc starts out with a new (indeterminate) value for display.
To solve this, display needs to have static storage duration. The easiest way to accomplish this is to replace
COLORREF *display;
with
static COLORREF *display;
This has 2 consequences:
The value stored in display survives separate invocations of WndProc.
The value stored in display is now properly zero-initialized.

Related

Calculate data from string like "1 + 1" = 2 in WinAPI C [duplicate]

This question already has answers here:
parsing math expression in c++
(6 answers)
Closed 1 year ago.
I'm currently trying to make pure WinAPI calculator that will have:
1 result textbox (where all data would be displayed)
some buttons like plus, minus, 1, 2 etc (on click, these will append text like 1,+,2 etc to Result textbox)
So now, suppose the result textbox contains string like 1 + 1, 7 / 2, 2 * 2, 8 - 8 etc, How can I invoke these strings to return data like 2, 3.5, 4, 0 respectively?
Is there any standard api in WinAPI by which I can invoke the calculation inside a string? Or do I need to make my own?
I'm using C WinAPI.
And here I got manage to complete UI and append text via buttons. Please see code:
#include <windows.h>
int IDC_result = 16;
int w = 50;
int h = 50;
void DrawButton(HWND hwnd, const char* Text, int x, int y, int code)
{
CreateWindowW(TEXT("button"), (LPCWSTR)Text, WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, x, y, w, h, hwnd, (HMENU)code, NULL, NULL);
}
const char* texts[] =
{
"7","8","9","/",
"4","5","6","*",
"1","2","3","-",
"0",".","=","+"
};
int textsLenght = (int)(sizeof(texts) / sizeof(texts[0]));
HWND RESULTS;
void DrawControls(HWND hwnd)
{
int TotalColms = 4;
RESULTS = CreateWindowEx(WS_EX_TRANSPARENT, TEXT("Edit"), TEXT(""), WS_CHILD | WS_VISIBLE | SS_LEFT | WS_SYSMENU, w * 1, h - 25, w * TotalColms, h - 30, hwnd, (HMENU)IDC_result, NULL, NULL);
int colm = 1;
int row = 1;
for(int text = 0; text < textsLenght; text++)
{
DrawButton(hwnd,texts[text],w * colm,h * row,text);
if (textsLenght / colm == TotalColms)
{
colm = 0;
row++;
}
colm++;
}
}
void appendText(LPARAM Text)
{
int Lenght = GetWindowTextLength(RESULTS);
SendMessageW(RESULTS, EM_SETSEL, Lenght, Lenght);
SendMessageW(RESULTS, EM_REPLACESEL, TRUE, Text);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
DrawControls(hwnd);
break;
case WM_COMMAND:
{
int no = LOWORD(wParam);
if (no > -1 && no < textsLenght)
{
appendText((LPARAM)texts[no]);
}
break;
}
case WM_DESTROY: PostQuitMessage(0);
default: return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
MSG msg;
WNDCLASS wc;
HWND hwnd;
ZeroMemory(&wc, sizeof wc);
wc.hInstance = hInstance;
wc.lpszClassName = L"Calculator";
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.style = CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW;
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
if (FALSE == RegisterClass(&wc)) return 0;
hwnd = CreateWindowW(
L"Calculator",L"Calculator"
,WS_OVERLAPPEDWINDOW | WS_VISIBLE,CW_USEDEFAULT,CW_USEDEFAULT,
300,500
,0,0,hInstance,0);
if (NULL == hwnd) return 0;
while (GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
Please comment, if anything unclear.
Is there any standard api in winapi by which we can invoke the
calculation inside a string ? or I need to make my own ?
No there is no standard API for this; you must either make your own, or more practically find a pre-made library for this.
Another option if you want something that "just works even though it's extremely dirty/hacky/insecure" is to find a way to invoke powershell from your app and capture the output.

Loosing mouse cursor when changing GetStockObject(WHITE_BRUSH) to GetStockObject(GREY_BRUSH)

I am trying to learn win32 API using Programming Windows fifth Edition.
As I was experimenting with some Identifiers I noticed something that I am not able to understand why is happening.I` ll be more specific, here is my code:
#include<Windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int
WINAPI
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT("HELLOWIN");
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_SHIELD);
wndclass.hCursor = LoadCursor(NULL, IDC_CROSS);
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
if (!RegisterClass(&wndclass))
{
MessageBox(0, TEXT("This Programm Requires WINNT!"), szAppName, MB_ICONERROR);
return(0);
}
hwnd = CreateWindow(szAppName, //window class name
TEXT("The Hello Program"), //window caption
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, //parent window handle(we have top-level window)
NULL, //window menu handle
hInstance, //programm instances handle
NULL); //creation parameters
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
switch (message)
{
case WM_CREATE:
{
PlaySound(TEXT("D:\\mp3\\aywy._&_EphRem_-_Adderall.wav"), NULL, SND_FILENAME | SND_ASYNC);
return 0;
} break;
case WM_PAINT:
{
hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rect);
DrawText(hdc, TEXT("Hello, Windows 98!"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint(hwnd, &ps);
return 0;
} break;
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
} break;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
With this code everything works great and as expected but...
when i change:
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
to
wndclass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
the cursor icon is lost on the background and is only visisble in the small line
in which i use drawText().What confuses me is that this doesnt happen when my background is white(WHITE_BRUSH).
Could someone explain why?
PS:If this behaviour is explained later in the book (I am finishing chapter 3 currently) just type Read more so i don`t waste you time.
Thank you in advance.
What is probably happening is that the 'cross' cursor that you are using is a very thin cursor implemented (either by windows or by the hardware) by NEGating the underlying pixels instead of painting above them. This works fine for all colors except the 0x808080 gray, because negating 0x808080 still gives 0x808080, so the cursor is invisible. Try using light gray, dark gray, or another cursor which is not so thin.

Why is my client rectangle drawing behaving bizarrely (pictures provided) if I try to inset the client rectangle in my WM_NCCALCSIZE?

I'm trying to implement an equivalent to Cocoa's NSPopover/GTK+'s GtkPopover but on Windows using the raw Windows API. So far, I have most things working right, but I can't get the client rectangle to work... in any sensible fashion.
If I comment out my WM_PAINT handler and my WM_NCCALCSIZE below, here's what happens:
Now, if I enable WM_NCCALCSIZE, a good chunk of that red border goes away:
And if I enable my WM_PAINT, this happens. Notice that the part in the above that's black but supposed to be red stays black, but the part that's red is now COLOR_ACTIVECAPTION.
Images are from wine.
Windows XP is even worse: the GetDCEx() call (which is straight out of MSDN) fails with no last error code set, and changing it to use the seemingly equivalent GetWindowDC() results in a transparent correct red border, a transparent correct (!) red border, and the whole window having the titlebar color, respectively. wine output doesn't change.
Am I misunderstanding something about WM_NCCALCSIZE? I know all inputs and outputs are in the same coordinate space, so I assumed I could just mainpulate those coordinates and call it a day. I did try handling the valid rectangles fields (rgrc[1]/rgrc[2]), both by setting them to empty rectangles and by making rgrc[1] set to the new client rect, but neither fixed the issue here.
The MoveWindow() also doesn't seem to be it; if I remove that and keep the popover at its initial size, it still draws as above, with the same corrupt red border problem.
Thanks.
Here is the code. Because it is a test to figure out what to do, there's no error checking yet. The final code will have full error checking.
// 9 october 2014
#define UNICODE
#define _UNICODE
#define STRICT
#define STRICT_TYPED_ITEMIDS
// get Windows version right; right now Windows XP
#define WINVER 0x0501
#define _WIN32_WINNT 0x0501
#define _WIN32_WINDOWS 0x0501 /* according to Microsoft's winperf.h */
#define _WIN32_IE 0x0600 /* according to Microsoft's sdkddkver.h */
#define NTDDI_VERSION 0x05010000 /* according to Microsoft's sdkddkver.h */
#include <windows.h>
#include <commctrl.h>
#include <stdint.h>
#include <uxtheme.h>
#include <string.h>
#include <wchar.h>
#include <windowsx.h>
#include <vsstyle.h>
#include <vssym32.h>
// #qo LIBS: user32 kernel32 gdi32
// TODO
// - investigate visual styles
// - put the client and non-client areas in the right place
// - make sure redrawing is correct (especially for backgrounds)
// - wine: BLACK_PEN draws a white line? (might change later so eh)
// - should the parent window appear deactivated?
HWND popover;
#define ARROWHEIGHT 8
#define ARROWWIDTH 8 /* should be the same for smooth lines */
LRESULT CALLBACK popoverproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC dc;
HRGN region;
POINT pt;
RECT r;
LONG width;
LONG height;
switch (uMsg) {
case WM_NCPAINT:
GetWindowRect(hwnd, &r);
width = r.right - r.left;
height = r.bottom - r.top;
dc = GetDCEx(hwnd, (HRGN) wParam, DCX_WINDOW | DCX_INTERSECTRGN);
if (dc == NULL) abort();
BeginPath(dc);
r.left = 0; r.top = 0; // everything's in device coordinates
pt.x = r.left;
pt.y = r.top + ARROWHEIGHT;
if (MoveToEx(dc, pt.x, pt.y, NULL) == 0) abort();
pt.y += height - ARROWHEIGHT;
if (LineTo(dc, pt.x, pt.y) == 0) abort();
pt.x += width;
LineTo(dc, pt.x, pt.y);
pt.y -= height - ARROWHEIGHT;
LineTo(dc, pt.x, pt.y);
pt.x -= (width / 2) - ARROWWIDTH;
LineTo(dc, pt.x, pt.y);
pt.x -= ARROWWIDTH;
pt.y -= ARROWHEIGHT;
LineTo(dc, pt.x, pt.y);
pt.x -= ARROWWIDTH;
pt.y += ARROWHEIGHT;
LineTo(dc, pt.x, pt.y);
pt.x = 0;
LineTo(dc, pt.x, pt.y);
EndPath(dc);
SetDCBrushColor(dc, RGB(255, 0, 0));
region = PathToRegion(dc);
FrameRgn(dc, region, GetStockObject(DC_BRUSH), 1, 1);
SetWindowRgn(hwnd, region, TRUE);
ReleaseDC(hwnd, dc);
return 0;
case WM_NCCALCSIZE:
{
RECT *r = (RECT *) lParam;
NCCALCSIZE_PARAMS *np = (NCCALCSIZE_PARAMS *) lParam;
if (wParam != FALSE)
r = &np->rgrc[0];
printf("%d | %d %d %d %d\n", wParam, r->left, r->top, r->right, r->bottom);
r->left++;
r->top++;
r->right--;
r->bottom--;
r->top += ARROWHEIGHT;
return 0;
}
case WM_ERASEBKGND:
return (LRESULT) GetStockObject(HOLLOW_BRUSH);
case WM_PAINT:
dc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &r);
FillRect(dc, &r, GetSysColorBrush(COLOR_ACTIVECAPTION));
EndPaint(hwnd, &ps);
return 0;
}
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
LRESULT CALLBACK wndproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg) {
case WM_COMMAND:
if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == 100) {
MoveWindow(popover, 50, 50, 200, 200, TRUE);
ShowWindow(popover, SW_SHOW);
UpdateWindow(popover);
return 0;
}
break;
case WM_CLOSE:
PostQuitMessage(0);
return 0;
}
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
int main(int argc, char *argv[])
{
WNDCLASSW wc;
HWND mainwin, button;
MSG msg;
ZeroMemory(&wc, sizeof (WNDCLASSW));
wc.lpszClassName = L"popover";
wc.lpfnWndProc = popoverproc;
wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
wc.style = CS_DROPSHADOW | CS_NOCLOSE;
if (RegisterClassW(&wc) == 0)
abort();
popover = CreateWindowExW(WS_EX_TOPMOST,
L"popover", L"",
WS_POPUP,
0, 0, 150, 100,
NULL, NULL, NULL, NULL);
if (popover == NULL)
abort();
ZeroMemory(&wc, sizeof (WNDCLASSW));
wc.lpszClassName = L"mainwin";
wc.lpfnWndProc = wndproc;
wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
if (RegisterClassW(&wc) == 0)
abort();
mainwin = CreateWindowExW(0,
L"mainwin", L"Main Window",
WS_OVERLAPPEDWINDOW,
0, 0, 150, 100,
NULL, NULL, NULL, NULL);
if (mainwin == NULL)
abort();
button = CreateWindowExW(0,
L"button", L"Click Me",
BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE,
20, 20, 100, 40,
mainwin, (HMENU) 100, NULL, NULL);
if (button == NULL)
abort();
ShowWindow(mainwin, SW_SHOWDEFAULT);
if (UpdateWindow(mainwin) == 0)
abort();
while (GetMessageW(&msg, NULL, 0, 0) > 0) {
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
return 0;
}

Missing ';' identifier before PVOID64

I saw another post addressing this issue however the asker was apparently including winnt.h instead of windows.h (which supposedly includes winnt.h)
I'm using windows.h but still getting this issue.
I've tried using Visual Studio 2010 Express and Ultimate and both produce this error.
Has anyone encountered this before?
Here is the code:
#include<Windows.h>
#include<d3d9.h>
#include<time.h>
#include<d3dx.h>
#define APPTITLE "Create Surface"
#define KEY_DOWN(vk_code)((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEY_UP(vk_code)((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
LRESULT WINAPI WinProc(HWND, UINT, WPARAM, LPARAM);
ATOM MyRegisterClass(HINSTANCE);
int Game_Init(HWND);
void Game_Run(HWND);
void Game_End(HWND);
LPDIRECT3D9 d3d = NULL;
LPDIRECT3DDEVICE9 d3ddev = NULL;
LPDIRECT3DSURFACE9 backbuffer = NULL, surface = NULL;
LRESULT WINAPI WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){
switch(msg){
case WM_DESTROY:
Game_End(hWnd);
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
ATOM MyRegisterClass(HINSTANCE hInstance){
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WinProc;
wc.cbWndExtra = 0;
wc.cbClsExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = APPTITLE;
wc.hIconSm = NULL;
return RegisterClassEx(&wc);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
MSG msg;
MyRegisterClass(hInstance);
HWND hWnd;
hWnd = CreateWindow(
APPTITLE,
APPTITLE,
WS_EX_TOPMOST | WS_VISIBLE | WS_POPUP,
CW_USEDEFAULT,
CW_USEDEFAULT,
SCREEN_WIDTH,
SCREEN_HEIGHT,
NULL,
NULL,
hInstance,
NULL);
if(!hWnd)
return FALSE;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
if(!Game_Init(hWnd))
return 0;
int done = 0;
while(!done){
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
if(msg.message == WM_QUIT)
done = 1;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
Game_Run(hWnd);
}
return msg.wParam;
}
int Game_Init(HWND hWnd){
HRESULT result;
d3d = Direct3DCreate9(D3D_SDK_VERSION);
if(d3d == NULL){
MessageBox(hWnd, "Failed to initialise d3d", "Error", MB_OK);
return 0;
}
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = FALSE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
d3dpp.BackBufferCount = 1;
d3dpp.BackBufferHeight = SCREEN_HEIGHT;
d3dpp.BackBufferWidth = SCREEN_WIDTH;
d3dpp.hDeviceWindow = hWnd;
d3d->CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&d3ddev);
if(d3ddev == NULL){
MessageBox(hWnd, "Failed to initialise Direct3D device", "Error", MB_OK);
return 0;
}
srand(time(NULL));
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
result = d3ddev->CreateOffscreenPlainSurface(
100,
100,
D3DFMT_X8R8G8B8,
D3DPOOL_DEFAULT,
&surface,
NULL);
if(!result)
return 1;
return 1;
}
void Game_Run(HWND hWnd){
RECT rect;
int r,g,b;
if(d3ddev == NULL)
return;
if(d3ddev->BeginScene()){
r = rand() % 255;
g = rand() % 255;
b = rand() % 255;
d3ddev->ColorFill(surface, NULL, D3DCOLOR_XRGB(r,g,b));
rect.left = rand() % SCREEN_WIDTH / 2;
rect.right = rect.left + rand() % SCREEN_WIDTH / 2;
rect.top = rand() % SCREEN_HEIGHT;
rect.bottom = rect.top + rand() % SCREEN_HEIGHT / 2;
d3ddev->StretchRect(surface, NULL, backbuffer, &rect, D3DTEXF_NONE);
d3ddev->EndScene();
}
d3ddev->Present(NULL, NULL, NULL, NULL);
if(KEY_DOWN(VK_ESCAPE))
PostMessage(hWnd, WM_DESTROY, 0, 0);
}
void Game_End(HWND hWnd){
surface->Release();
if(d3ddev != NULL)
d3ddev->Release();
if(d3d != NULL)
d3d->Release();
}
And the link for the post I mentioned above:
syntax error : missing ';' before identifier 'PVOID64' when compiling winnt.h
This is because the order of the VC++ include directory, try to put the path windows SDK before DirectX SDK, as below.
So I think I stumbled across a solution when trying to sort this on a different laptop.
There's something that seems to get installed with the Windows SDK called Windows SDK Configuration Tool. Running that detects which versions of the SDK you have installed then allows you to select which one to use. It then configures all versions of Visual Studio you have to use the selected version.
I think that solved the issue - not had a proper chance to fully check yet - I also uninstalled all versions of Visual Studio I had with all related components and reinstalled just the one I needed (for the time being - might install other versions later to see if that potentially cause a conflict of sorts).
Anyway, just figured I'd leave a possible solution on here for anyone that happens across this thread.
\,,/[>.<]\,,/

Why is my Windows program trying to call main() instead of WinMain()?

I'm trying to make my first steps to OpenGL.
However it seems that it will not happen because of this error coming while trying to debug the solution:
MSVCRTD.lib(crtexe.obj) : error LNK2019: unresolved external symbol main referenced in function __tmainCRTStartup
I understand that the complier wants to see int main() ..., but doesn't it see WinMain call?
Here is the code:
#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct {
HWND hWnd;
} Glab_t;
static Glab_t glab;
char szClassName[ ] = "GLab";
static LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
case WM_DESTROY:
PostQuitMessage (0);
break;
default:
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
MSG messages;
RECT rect;
WNDCLASSEX wndClass;
int screenWidth, screenHeight;
int x, y, w, h;
screenWidth = GetSystemMetrics(SM_CXSCREEN);
screenHeight = GetSystemMetrics(SM_CYSCREEN);
rect.left = (screenWidth - 582) / 2;
rect.top = (screenHeight - 358) / 2;
rect.right = rect.left + 582;
rect.bottom = rect.top + 358;
x = rect.left;
y = rect.top;
w = 640;
h = 480;
wndClass.hInstance = hInstance;
wndClass.lpszClassName = szClassName;
wndClass.lpfnWndProc = WindowProcedure;
wndClass.style = CS_DBLCLKS;
wndClass.cbSize = sizeof (WNDCLASSEX);
wndClass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wndClass.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wndClass.hCursor = LoadCursor (NULL, IDC_ARROW);
wndClass.lpszMenuName = NULL;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
if (!RegisterClassEx (&wndClass)) {
return 0;
}
glab.hWnd = CreateWindowEx (
0,
szClassName,
"GLab - OpenGL",
WS_OVERLAPPEDWINDOW,
x,
y,
w,
h,
HWND_DESKTOP,
NULL,
hInstance,
NULL
);
ShowWindow (glab.hWnd, nCmdShow);
while (GetMessage (&messages, NULL, 0, 0)) {
TranslateMessage(&messages);
DispatchMessage(&messages);
}
return true;
}
I'm using MS Visual C++ 2010 Express.
You have a project of subsystem Console instead of Windows. Change it from your project properties, and it will work. That's in Linker -> System -> SubSystem.
You have to change the properties for the project; a Console project will generally look for a main() function, whereas a Windows project looks for WinMain() instead.

Resources