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...
Related
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;
}
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.
I want to catch message of WM_DEVICECHANGE.But, there is a problem which i can not understand.I want to see when usb or cd inserted.Maybe my notification filter is wrong.
I m using radstudio and the language of its c,also its commandline application.I think everything is obvious in code.What am i doing wrong,i created window for only getting messages.Also i did not understand how it message going to WndProc from message loop.
#pragma hdrstop
#pragma argsused
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <dbt.h>
LRESULT CALLBACK WndProc(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
switch (uiMsg)
{
case WM_DEVICECHANGE:
{
MessageBox(0,"a","b",1);
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
BOOL bRet;
HANDLE a;
HWND lua;
HANDLE hInstance;
MSG msg;
WNDCLASSEX wndClass;
HANDLE hVolNotify;
DEV_BROADCAST_DEVICEINTERFACE dbh;
DEV_BROADCAST_VOLUME NotificationFilter;
lua = CreateWindow("lua", NULL, WS_MINIMIZE, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);
wndClass.lpfnWndProc = WndProc;
ZeroMemory(&NotificationFilter, sizeof (NotificationFilter));
NotificationFilter.dbcv_size = sizeof (NotificationFilter);
NotificationFilter.dbcv_devicetype = DBT_DEVTYP_VOLUME;
a = RegisterDeviceNotification(lua,&NotificationFilter,DEVICE_NOTIFY_WINDOW_HANDLE);
while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
{
MessageBox(0,"o","b",1);
if (bRet == -1)
{
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
What am i doing wrong,i created window for only getting messages.
You are asking CreateWindow() to create a window of class "lua" but you have not actually registered the "lua" class via RegisterClass/Ex() before calling CreateWindow(), and you are not checking to see if CreateWindow() returns a NULL window handle on failure.
Also i did not understand how it message going to WndProc from message loop.
That is handled by DispatchMessage(). You need to assign wndClass.lpfnWndProc and register it with RegisterClass() before calling CreateWindow(). Afterwards, when DispatchMessage() sees a message that targets the window created by CreateWindow(), it knows that WndProc() has been associated with that window and will call it directly, passing it the message.
Try this instead:
#pragma hdrstop
#pragma argsused
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <dbt.h>
LRESULT CALLBACK WndProc(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
if (uiMsg == WM_DEVICECHANGE)
{
MessageBox(NULL, TEXT("WM_DEVICECHANGE"), TEXT("WndProc"), MB_OK);
return 0;
}
return DefWindowProc(hWnd, uiMsg, wParam, lParam);
}
int _tmain(int argc, _TCHAR* argv[])
{
HINSTANCE hInstance = reinterpret_cast<HINSTANCE>(GetModuleHandle(NULL));
WNDCLASS wndClass = {0};
wndClass.lpfnWndProc = &WndProc;
wndClass.lpszClassName = TEXT("lua");
wndClass.hInstance = hInstance;
if (RegisterClass(&wndClass))
{
HWND lua = CreateWindow(wndClass.lpszClassName, NULL, 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
if (lua != NULL)
{
DEV_BROADCAST_VOLUME NotificationFilter = {0};
NotificationFilter.dbcv_size = sizeof(NotificationFilter);
NotificationFilter.dbcv_devicetype = DBT_DEVTYP_VOLUME;
HDEVNOTIFY hVolNotify = RegisterDeviceNotification(lua, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);
if (hVolNotify != NULL)
{
MSG msg;
while( GetMessage(&msg, NULL, 0, 0) > 0 )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
UnregisterDeviceNotification(hVolNotify);
}
DestroyWindow(lua);
}
UnregisterClass(wndClass.lpszClassName, hInstance);
}
return 0;
}
For added measure, you can use CreateWindowEx() instead of CreateWindow() to create a message-only window instead, if desired:
HWND lua = CreateWindowEx(0, wndClass.lpszClassName, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, hInstance, NULL);
You need to set the dbcv_unitmask field of the DEV_BROADCAST_VOLUME structure to indicate which drive letters you're interested in. If you want to see media changes you also need to set the DBTF_MEDIA flag in the dbcv_flags field.
I am trying to compile a basic hello word winform application with gcc on Win 7.
The code is this:
/*
WINHELLO.C
"Hello, world!", Win32 style.
*/
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
/* WinMain(), our entry point */
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR szCmdLine, int iCmdShow) {
static char szAppName[] = "winhello";
HWND hwnd;
MSG msg;
WNDCLASSEX wndclass;
/* Fill in WNDCLASSEX struct members */
wndclass.cbSize = sizeof(wndclass);
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.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wndclass.lpszClassName = szAppName;
wndclass.lpszMenuName = NULL;
/* Register a new window class with Windows */
RegisterClassEx(&wndclass);
/* Create a window based on our new class */
hwnd = CreateWindow(szAppName, "Hello, world!",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);
/* Show and update our window */
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
/* Retrieve and process messages until we get WM_QUIT */
while ( GetMessage(&msg, NULL, 0, 0) ) {
TranslateMessage(&msg); /* for certain keyboard messages */
DispatchMessage(&msg); /* send message to WndProc */
}
/* Exit with status specified in WM_QUIT message */
return msg.wParam;
}
/* Window procedure */
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) {
PAINTSTRUCT ps;
HDC hdc;
/* Switch according to what type of message we have received */
switch ( iMsg ) {
case WM_PAINT:
/* We receive WM_PAINT every time window is updated */
hdc = BeginPaint(hwnd, &ps);
TextOut(hdc, 100, 100, "Hello, world!", 13);
EndPaint(hwnd, &ps);
return 0;
case WM_DESTROY:
/* Window has been destroyed, so exit cleanly */
PostQuitMessage(0);
return 0;
}
/* Send any messages we don't handle to default window procedure */
return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
The command I give to the compiler is gcc C:\Users\Bobby\Desktop\myfile.c
Well, it looks for libraries:
C:\Users\Bobby\desktop>gcc C:\Users\Bobby\Desktop\myfile.c
C:\Users\Bobby\AppData\Local\Temp\ccT0bq97.o:myfile.c:(.text+0x88): undefined reference to `GetStockObject#4'
C:\Users\Bobby\AppData\Local\Temp\ccT0bq97.o:myfile.c:(.text+0x1db): undefined reference to `TextOutA#20'
collect2: ld returned 1 exit status
PS C:\Users\Scruffy\desktop> .\build.bat
C:\Users\Bobby\desktop>gcc C:\Users\Bobby\Desktop\myfile.c -I Gdi32.lib
C:\Users\Bobby\AppData\Local\Temp\ccylV5js.o:myfile.c:(.text+0x88): undefined reference to `GetStockObject#4'
C:\Users\Bobby\AppData\Local\Temp\ccylV5js.o:myfile.c:(.text+0x1db): undefined reference to `TextOutA#20'
collect2: ld returned 1 exit status
PS C:\Users\Bobby\desktop> C:\MinGW\
I did some googling and well I found out that this first GetStockObject#4 is in a file called Gdi32.lib . So i searched my harddrive and through MinGW and could not locate it. Where is the Lib to locate this function and what is the way to link to it? Also I think I must link to TextOutA#20
Instead of linking against GDI32 explicitly, you should use the -mwindows subsystem option in this case:
gcc -Wall -mwindows winhello.c -o winhello.exe
Note:
gcc et al. prefer .a files over .lib, so you should've been looking for libgdi32.a. You can still link against either by giving the filename as a parameter:
gcc src.c /path/to/example1.lib /path/to/libexample2.a
or using the -l option for .a files:
gcc src.c /path/to/example1.lib -L/path/to -lexample2
Windows DLL needs so-called import library for the linker to resolve references to its exported functions. Microsoft supplies import librarirs, including Gdi32.lib, with Windows SDK. This file should not be deployed to end users.
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.
\,,/[>.<]\,,/