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

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.

Related

How to display raw array of pixels to the screen?

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.

(C) Incompatible pointer type [LPCWSTR]

I am receiving incompatible pointer type everywhere when I am trying to work with unicode LPCWSTR types.
I am completely stuck no matter what I do, tried to search for a answer lots of times and still no hope!
My code:
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include "Mouse.h"
#include "Keyboard.h"
//#define APP_WindowClassName "MOUSE_CLICKER"
//#define APP_WindowTitle "Mouse Clicker"
LRESULT CALLBACK app_WindowProcedure (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // Arg1 - A handle to the current instance of the application, Arg 2 - ???, Arg 3 - Arguments, Arg 4 - Controls how the window is to be shown.
WNDCLASSEXW main_WindowClass = { };
main_WindowClass.cbSize = sizeof(WNDCLASSEXA);
main_WindowClass.cbClsExtra = 0;
main_WindowClass.cbWndExtra = 0;
main_WindowClass.hInstance = hInstance;
main_WindowClass.lpfnWndProc = app_WindowProcedure;
main_WindowClass.lpszClassName = TEXT("MOUSE_CLICKER");
main_WindowClass.lpszMenuName = NULL;
main_WindowClass.hbrBackground = (HBRUSH) (TEXT(COLOR_BACKGROUND));
main_WindowClass.hCursor = LoadCursorW (NULL, TEXT(IDC_ARROW));
main_WindowClass.hIcon = LoadIconW(NULL, TEXT(IDI_APPLICATION));
main_WindowClass.hIconSm = LoadIconW(NULL, TEXT(IDI_APPLICATION));
main_WindowClass.style = CS_DBLCLKS;
//CS_HREDRAW | CS_VREDRAW a
if (RegisterClassExW(&main_WindowClass) == 0) {
printf ("[CRITICAL] main_WindowClass cannot be registered!");
return -1;
}
HWND main_WindowHandle = CreateWindowExW (0, TEXT("MOUSE_CLICKER"), TEXT("MouseClicker"), WS_OVERLAPPEDWINDOW, 0, 0, 800, 600, NULL, NULL, hInstance, NULL);
if (main_WindowHandle == NULL) {
return -1;
}
ShowWindow(main_WindowHandle, nCmdShow);
printf("Unicode: %d", IsWindowUnicode(main_WindowHandle));
MSG ProcessingMessage;
while (GetMessage(&ProcessingMessage, NULL, 0, 0)) {
TranslateMessage(&ProcessingMessage);
DispatchMessage(&ProcessingMessage);
}
return ProcessingMessage.wParam;
}
My build log picture link:
PS: I am a beginner in C (still learning) and understandable descriptive information on what I am doing wrong would be nice.
PS2: To avoid confusion this is pure C, NOT C++.
Solution code:
#if defined(UNICODE) && !defined(_UNICODE)
#define _UNICODE
#elif defined(_UNICODE) && !defined(UNICODE)
#define UNICODE
#endif
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>
#include <tchar.h>
#include "Mouse.h"
#include "Keyboard.h"
LRESULT CALLBACK app_WindowProcedure (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // Arg1 - A handle to the current instance of the application, Arg 2 - ???, Arg 3 - Arguments, Arg 4 - Controls how the window is to be shown.
WNDCLASSEXW main_WindowClass = { };
main_WindowClass.cbSize = sizeof(WNDCLASSEXA);
main_WindowClass.cbClsExtra = 0;
main_WindowClass.cbWndExtra = 0;
main_WindowClass.hInstance = hInstance;
main_WindowClass.lpfnWndProc = app_WindowProcedure;
main_WindowClass.lpszClassName = L"MOUSE_CLICKER";
main_WindowClass.lpszMenuName = NULL;
main_WindowClass.hbrBackground = (HBRUSH) (COLOR_BACKGROUND);
main_WindowClass.hCursor = LoadCursorW (NULL, (LPCWSTR) IDC_ARROW);
main_WindowClass.hIcon = LoadIconW(NULL, (LPCWSTR) IDI_APPLICATION);
main_WindowClass.hIconSm = LoadIconW(NULL, (LPCWSTR) IDI_APPLICATION);
main_WindowClass.style = CS_DBLCLKS;
//CS_HREDRAW | CS_VREDRAW a
if (RegisterClassExW(&main_WindowClass) == 0) {
printf ("[CRITICAL] main_WindowClass cannot be registered!");
return -1;
}
HWND main_WindowHandle = CreateWindowExW (0, L"MOUSE_CLICKER", L"MouseClicker", WS_OVERLAPPEDWINDOW, 0, 0, 800, 600, NULL, NULL, hInstance, NULL);
if (main_WindowHandle == NULL) {
return -1;
}
ShowWindow(main_WindowHandle, nCmdShow);
printf("Unicode: %d", IsWindowUnicode(main_WindowHandle));
MSG ProcessingMessage;
while (GetMessage(&ProcessingMessage, NULL, 0, 0)) {
TranslateMessage(&ProcessingMessage);
DispatchMessage(&ProcessingMessage);
}
return ProcessingMessage.wParam;
}
Define UNICODE in your project.
Based on whether UNICODE is defined, TEXT expands to either LPSTR or LPWSTR. You are explicitly calling *W versions of WinAPI functions but pass LPSTR instead of LPWSTR. Prefixing string literal with L should work actually. Maybe you used it as L("foo") - it won't work this way. You need to use L"foo".
Overall, if you use TEXT, you should use WinAPI functions without suffixes, so that code will compile both with and without UNICODE defined. If you explicitly use *W functions, use L"" strings.
There are several approaches you can take to get this to work; since you're already going down the path of using Generic-Text Mappings in Tchar.h, let's continue on that route.
Here is the main body of your program, revised to run as Unicode when your project is set to build Unicode.
(A side "benefit", if you would call it that, is that you can run your application as an ASCII application as well just by changing the character set of the project.)
LRESULT CALLBACK app_WindowProcedure(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { // Arg1 - A handle to the current instance of the application, Arg 2 - ???, Arg 3 - Arguments, Arg 4 - Controls how the window is to be shown.
WNDCLASSEX main_WindowClass = {};
main_WindowClass.cbSize = sizeof(WNDCLASSEX);
main_WindowClass.cbClsExtra = 0;
main_WindowClass.cbWndExtra = 0;
main_WindowClass.hInstance = hInstance;
main_WindowClass.lpfnWndProc = app_WindowProcedure;
main_WindowClass.lpszClassName = TEXT("MOUSE_CLICKER");
main_WindowClass.lpszMenuName = NULL;
main_WindowClass.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
main_WindowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
main_WindowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
main_WindowClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
main_WindowClass.style = CS_DBLCLKS;
//CS_HREDRAW | CS_VREDRAW a
if (RegisterClassEx(&main_WindowClass) == 0) {
_tprintf(TEXT("[CRITICAL] main_WindowClass cannot be registered!"));
return -1;
}
HWND main_WindowHandle = CreateWindowEx(0, TEXT("MOUSE_CLICKER"), TEXT("MouseClicker"), WS_OVERLAPPEDWINDOW, 0, 0, 800, 600, NULL, NULL, hInstance, NULL);
if (main_WindowHandle == NULL) {
return -1;
}
ShowWindow(main_WindowHandle, nCmdShow);
_tprintf(TEXT("Unicode: %d"), IsWindowUnicode(main_WindowHandle));
MSG ProcessingMessage;
while (GetMessage(&ProcessingMessage, NULL, 0, 0)) {
TranslateMessage(&ProcessingMessage);
DispatchMessage(&ProcessingMessage);
}
return ProcessingMessage.wParam;
}
Note that Unicode-specific function calls were replaced with their generic counterparts (e.g., DefWindowProcW() is now DefWindowProc(); RegisterClassExW() is now RegisterClassEx(); printf() is now _tprintf(), and so on). All text is wrapped in the TEXT() macro.
An alternative approach, as you worked in part, is to make all API calls the ...W versions for Unicode functions, and to hard-code text using the L prefix to use Unicode text.
A good rule of thumb is to try to pick one technique or another, and apply it consistently and across the board.
This should work
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include "Mouse.h"
#include "Keyboard.h"
//#define APP_WindowClassName "MOUSE_CLICKER"
//#define APP_WindowTitle "Mouse Clicker"
LRESULT CALLBACK app_WindowProcedure(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // Arg1 - A handle to the current instance of the application, Arg 2 - ???, Arg 3 - Arguments, Arg 4 - Controls how the window is to be shown.
WNDCLASSEXW main_WindowClass = *((WNDCLASSEXW*)malloc(sizeof(WNDCLASSEXW)));
main_WindowClass.cbSize = sizeof(WNDCLASSEXA);
main_WindowClass.cbClsExtra = 0;
main_WindowClass.cbWndExtra = 0;
main_WindowClass.hInstance = hInstance;
main_WindowClass.lpfnWndProc = app_WindowProcedure;
main_WindowClass.lpszClassName = L"MOUSE_CLICKER";
main_WindowClass.lpszMenuName = NULL;
main_WindowClass.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
main_WindowClass.hCursor = LoadCursorW(NULL, (LPWSTR)IDC_ARROW);
main_WindowClass.hIcon = LoadIconW(NULL, (LPWSTR)IDI_APPLICATION);
main_WindowClass.hIconSm = LoadIconW(NULL, (LPWSTR)IDI_APPLICATION);
main_WindowClass.style = CS_DBLCLKS;
//CS_HREDRAW | CS_VREDRAW a
if (RegisterClassExW(&main_WindowClass) == 0) {
printf("[CRITICAL] main_WindowClass cannot be registered!");
return -1;
}
HWND main_WindowHandle = CreateWindowExW(0, L"MOUSE_CLICKER", L"MouseClicker", WS_OVERLAPPEDWINDOW, 0, 0, 800, 600, NULL, NULL, hInstance, NULL);
if (main_WindowHandle == NULL) {
return -1;
}
ShowWindow(main_WindowHandle, nCmdShow);
printf("Unicode: %d", IsWindowUnicode(main_WindowHandle));
MSG ProcessingMessage;
while (GetMessage(&ProcessingMessage, NULL, 0, 0)) {
TranslateMessage(&ProcessingMessage);
DispatchMessage(&ProcessingMessage);
}
return ProcessingMessage.wParam;
}

How to add gdi32.lib correctly from within the file? [duplicate]

This question already has answers here:
#pragma comment(lib, "xxx.lib") equivalent under Linux?
(3 answers)
Closed 6 years ago.
I'm currently having a problem with including the gdi32.lib in my C project on windows. The error occurs in the following code segment:
#include <windows.h>
#pragma comment(lib, "kernel32.lib")
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "gdi32.lib")
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
WNDCLASSEX wcx;
wcx.hbrBackground = CreateSolidBrush(0x000000);
....
}
When I compile with the -lgdi32 option, everything works just as expected, whereas I get a compiling error with the following command:
C:\projects\cpp>c++ project.cpp
C:\Users\LUKASW~1\AppData\Local\Temp\ccSKc5qg.o:project.cpp:(.text+0xe0):
undefined reference to `__imp_CreateSolidBrush'
collect2.exe: error: ld returned 1 exit status
Is there a way to link the libraries directly in a file rather than passing it to the compiler every time?
Here is the stripped down version for debugging:
#include <windows.h>
#pragma comment(lib, "kernel32.lib")
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "gdi32.lib")
static char szWindowClass[] = "debugging";
static char szTitle[] = "gdi32.lib test";
HINSTANCE hInst;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void GetDesktopResolution(int& w, int& h) {
RECT desktop;
GetWindowRect(GetDesktopWindow(), &desktop);
w = desktop.right;
h = desktop.bottom;
}
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
WNDCLASSEX wcx;
wcx.cbClsExtra = 0;
wcx.cbSize = sizeof(WNDCLASSEX);
wcx.cbWndExtra = 0;
wcx.hbrBackground = CreateSolidBrush(0x000000);
wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
wcx.hIcon = LoadIcon(hInst, IDI_APPLICATION);
wcx.hIconSm = LoadIcon(wcx.hInstance, IDI_APPLICATION);
wcx.hInstance = hInst;
wcx.lpfnWndProc = WndProc;
wcx.lpszClassName = szWindowClass;
wcx.lpszMenuName = NULL;
wcx.style = CS_HREDRAW | CS_VREDRAW;
RegisterClassEx(&wcx);
int x, y,
w = 600,
h = 600;
GetDesktopResolution(x, y);
HWND hWnd = CreateWindowEx(WS_EX_APPWINDOW, szWindowClass, szTitle, WS_POPUP, (x - w) / 2, (y - h) / 2, w, h, NULL, NULL, hInst, NULL);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
MSG msg;
while(GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
case WM_PAINT:
// empty
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
break;
}
return 0;
}
#pragma comment(lib, ...) is an MS Visual C/C++ pragma. You are using MinGW, which doesn't support that directive.
From what I read on this question, GCC and G++ don't have an equivalent pragma, so you will have to stick with the -l option.

MinGW isn't outputting executable or object file

I've just started using MinGW and I'm having an issue where it isn't outputting an executable or an object file, or anything really. After fixing a few errors everything compiles fine, but no executable is being outputted. When I first installed MinGW I tested it on a simple hello world program and everything worked correctly, but I'm trying to write a basic windows application and it's not working. I've worked with gcc before, but only briefly, I don't really know anything about it.
C:\Users\Cole\Dev\Hello Windows\>gcc win_main.c -o win_main
Here's the win_main.c file:
#include <windows.h>
#include <stdio.h>
/*
* Global Variables
*/
HWND g_hwnd = NULL;
HINSTANCE g_hinst = NULL;
/*
* Forward Declarations
*/
LRESULT CALLBACK win_proc(HWND h_wnd, UINT message, WPARAM w_param, LPARAM l_param);
HRESULT init_window(HINSTANCE h_instance, int cmd_show);
/*
* Main entry point to the application.
*/
int WINAPI WinMain(HINSTANCE h_instance, HINSTANCE h_previnstance, LPSTR cmd_line, int cmd_show) {
if(FAILED(init_window(h_instance, cmd_show)))
return -1;
MSG msg = {0};
while(GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
/*
* Register window class and create the window.
*/
HRESULT init_window(HINSTANCE h_instance, int cmd_show) {
/* Register window class. */
WNDCLASSEX wcx;
wcx.cbSize = sizeof(WNDCLASSEX);
wcx.style = CS_VREDRAW | CS_HREDRAW;
wcx.lpfnWndProc = win_proc;
wcx.cbClsExtra = 0;
wcx.cbWndExtra = 0;
wcx.hInstance = h_instance;
wcx.hIcon = NULL;
wcx.hIconSm = NULL;
wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
wcx.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcx.lpszMenuName = NULL;
wcx.lpszClassName = "BasicWindowClass";
if(!RegisterClassEx(&wcx)) {
printf("Failed to register window class.\n");
return E_FAIL;
}
/* Create the window. */
g_hinst = h_instance;
RECT rc = {0, 0, 640, 480};
AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
g_hwnd = CreateWindow("BasicWindowClass", "Windows Application", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, g_hinst, NULL);
if(g_hwnd == NULL) {
printf("Failed to create the window.\n");
return E_FAIL;
}
ShowWindow(g_hwnd, cmd_show);
return S_OK;
}
LRESULT CALLBACK win_proc(HWND h_wnd, UINT message, WPARAM w_param, LPARAM l_param) {
PAINTSTRUCT ps;
HDC hdc;
switch(message) {
case WM_PAINT:
hdc = BeginPaint(h_wnd, &ps);
EndPaint(h_wnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(h_wnd, message, w_param, l_param);
}
return 0;
}
You should add -mwindows gcc -mwindows win_main.c -o win_main .I guess your first program was using a 'main' function as entry point...

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.
\,,/[>.<]\,,/

Resources