LPCTSTR to LPWSTR conversion is not defined in Mingw32 in winnt.h - c

I am using mingw32, where I cant find type definition of LPCTSTR to LPCWSTR. But the same is defined in mingw64 as below.
typedef LPCWSTR PCTSTR,LPCTSTR;
But my code works fine in mingw32 without any error even I added LPCTSTR in my code, and if I change the compiler options to mingw64 I am getting lots of errors.
Winnt.h in mingw32:
typedef TCHAR TBYTE,*PTCH,*PTBYTE;
typedef TCHAR *LPTCH,*PTSTR,*LPTSTR,*LP,*PTCHAR;
typedef const TCHAR *LPCTSTR;
winnt.h in mingw64:
typedef LPWSTR LPTCH,PTCH;
typedef LPWSTR PTSTR,LPTSTR;
typedef LPCWSTR PCTSTR,LPCTSTR;
typedef LPUWSTR PUTSTR,LPUTSTR;
typedef LPCUWSTR PCUTSTR,LPCUTSTR;
typedef LPWSTR LP;
How to solve this? why I am not getting any error in mingw32, with UNICODE defined?

LPCTSTR is being defined in mingw32 as:
typedef const TCHAR *LPCTSTR;
When UNICODE is defined, TCHAR maps to WCHAR, making LPCTSTR equivilent to LPCWSTR.
When UNICODE is not defined, TCHAR maps to CHAR instead, making LPCTSTR equivilent to LPCSTR.

Related

How to define a function that using extern "C" modifier

In a DLL, a function is exported, and it is defined as:
extern "C" ULONGLONG WINAPI MyFun(CONST LPVOID lpParam);
Now in My app, I need to get the address of the function and invoke it, so I use
typedef ULONGLONG (WINAPI *MyFun) (CONST LPVOID lpParam);
and use
lpMyFun = (MyFun)GetProcAddress(hDLL, "MyFun");
In such a way, there is no way to put the extern "C" modifier in the typedef codeline, I using
extern "C" typedef ULONGLONG (WINAPI *MyFun) (CONST LPVOID lpParam);
but that will cause compiler error.
How to solve the problem?
Thanks

How to avoid "multiple definition" error for global constants?

I'm writing a C program using the Windows API. Each major function has its own file, and there is one header for the prototypes and includes and whatnot:
// Headers & global constants
#pragma once
#define _WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <WindowsX.h>
#include <Windef.h>
#define szClassName TEXT("EthicsPresentationWnd")
// Prototypes
LRESULT CALLBACK WindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
BOOL CALLBACK FontProc1(HWND hWnd, LPARAM lParam);
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd);
ATOM RegisterWindow(HINSTANCE hInstance);
The thing I'm irritated about is the #define szClassName line. I dislike using macros and would prefer to have a proper global variable, wchar_t szClassName[], but if I do that then the linker complains about multiply defined variables in each of the modules that include the header.
I thought the #pragma once directive would prevent this, but it didn't.
Is there any solution to this problem?
The solution to this is to have a separate declaration and definition...
Header (*.h; sorry, I don't know WinAPI type names, adapt as necessary):
extern const char szClassName[];
Implementation (*.c or *.cpp)
const char szClassName[] = "hello, world"
You're seeing the problem because a new symbol szClassName is being declared each time one of your *.c or *.cpp files includes the header (even with the include guards!); and that makes the linker confused (see below).
Do note that this will make sizeof(szClassName) not work anymore.
Further explanation:
After preprocessing, the compiler is basically seeing this:
file "a.c": const char someSymbol[] = <some text, don't care what right now>;
file "b.c": const char someSymbol[] = <some text, don't care if it's the same>;
file "c.c": const char someSymbol[] = <some text, ditto>;
When the linker is linking the object files (say, "a.obj", "b.obj" and "c.obj"), it sees the same symbol being defined with a new value (at least as far as the linker is concerned) --- and thus it fails with an error.
Place it in between
#ifndef GLOB_CONST_H
#define GLOB_CONST_H
// All macro definitions
// and type definitions
#endif
Use extern keyword to declare your global variables and put those declarations in this header file. After that you need to place the definition of all the variables in a .c file.
You can declare the variable as static so that each module that includes the .h file gets its own local unique copy that the linker will not complain about, as each copy will have local linkage instead of external linkage. This also eliminates the need for declaring the variable as extern and defining it in a separate .c file.
static const TCHAR szClassName[] = TEXT("EthicsPresentationWnd");
Or;
static const TCHAR *szClassName = TEXT("EthicsPresentationWnd");
Or:
static LPCTSTR szClassName = TEXT("EthicsPresentationWnd");
Use header guards in all your header file and declare a global variable in .c file and declare extern to that global variable in a header file.
#ifndef HEADER_FILE_NAME_H /* if not defined already */
#define HEADER_FILE_NAME_H
extern wchar_t szClassName[];
#endif
In any one of your .c file define the global variable.
wchar_t szClassName[];

Add elements to struct by define

I have a problem. I'm trying to add struct elements by previously defined constant.
This is sample code (OpenGL+WinAPI)
#define ENGINE_STRUCT \
HGLRC RenderingContext;\
HDC DeviceContext;
And then:
typedef struct SWINDOW {
ENGINE_STRUCT
HWND Handle;
HINSTANCE Instance;
CHAR* ClassName;
BOOL Fullscreen;
BOOL Active;
MSG Message;
} WINDOW;
Is this possible?
Yes it is possible, a macro is a simple textual substitution
http://www.cplusplus.com/doc/tutorial/preprocessor/
The preprocessor examines the code before actual compilation of code
begins and resolves all these directives before any code is actually
generated by regular statements.

argument of type const char* is incompatible with parameter of type "LPCWSTR"

I am trying to make a simple Message Box in C in Visual Studio 2012, but I am getting
the following error messages
argument of type const char* is incompatible with parameter of type "LPCWSTR"
err LNK2019:unresolved external symbol_main referenced in function_tmainCRTStartup
Here is the source code
#include<Windows.h>
int _stdcall WinMain(HINSTANCE hinstance,HINSTANCE hPrevinstance,LPSTR lpszCmdline,int nCmdShow)
{
MessageBox(0,"Hello","Title",0);
return(0);
}
Please Help
Thanks and Regards
To compile your code in Visual C++ you need to use Multi-Byte char WinAPI functions instead of Wide char ones.
Set Project -> Properties -> General -> Character Set option to Use Multi-Byte Character Set
I found it here https://stackoverflow.com/a/33001454/5646315
To make your code compile in both modes, enclose the strings in _T() and use the TCHAR equivalents
#include <tchar.h>
#include <windows.h>
int WINAPI _tWinMain(HINSTANCE hinstance, HINSTANCE hPrevinstance, LPTSTR lpszCmdLine, int nCmdShow)
{
MessageBox(0,_T("Hello"),_T("Title"),0);
return 0;
}
I recently ran in to this issue and did some research and thought I would document some of what I found here.
To start, when calling MessageBox(...), you are really just calling a macro (for backwards compatibility reasons) that is calling either MessageBoxA(...) for ANSI encoding or MessageBoxW(...) for Unicode encoding.
So if you are going to pass in an ANSI string with the default compiler setup in Visual Studio, you can call MessageBoxA(...) instead:
#include<Windows.h>
int _stdcall WinMain(HINSTANCE hinstance,HINSTANCE hPrevinstance,LPSTR lpszCmdline,int nCmdShow)
{
MessageBoxA(0,"Hello","Title",0);
return(0);
}
Full documentation for MessageBox(...) is located here: https://msdn.microsoft.com/en-us/library/windows/desktop/ms645505(v=vs.85).aspx
And to expand on what #cup said in their answer, you could use the _T() macro and continue to use MessageBox():
#include<tchar.h>
#include<Windows.h>
int _stdcall WinMain(HINSTANCE hinstance,HINSTANCE hPrevinstance,LPSTR lpszCmdline,int nCmdShow)
{
MessageBox(0,_T("Hello"),_T("Title"),0);
return(0);
}
The _T() macro is making the string "character set neutral". You could use this to setup all strings as Unicode by defining the symbol _UNICODE before you build (documentation).
Hope this information will help you and anyone else encountering this issue.
Yes whatever it was it was a wrong tutorial, you need to make it a long byte integer.
Try this:
#include<Windows.h>
int _stdcall WinMain(HINSTANCE hinstance,HINSTANCE hPrevinstance,LPSTR lpszCmdline,int nCmdShow)
{
MessageBox(0,L"Hello",L"Title",0);
return(0);
}

Can't link against WICConvertBitmapSource

I'd like to use a function from WindowsCodecs.dll, but MinGW has incomplete and missing WinAPI headers, as well as import libraries. Consider the following demo:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
// ---------- dummy declarations, because MinGW got no wincodec.h ----------
typedef REFGUID REFWICPixelFormatGUID;
typedef VOID IWICBitmapSource;
HRESULT WINAPI WICConvertBitmapSource(
REFWICPixelFormatGUID dstFormat,
IWICBitmapSource *pISrc,
IWICBitmapSource **ppIDst);
// -------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpLine, int nShow)
{
#ifdef LOAD_FROM_DLL
typedef HRESULT (WINAPI *PWICConvertBitmapSource)(
REFWICPixelFormatGUID, IWICBitmapSource *, IWICBitmapSource **);
HMODULE hDll = LoadLibrary("WindowsCodecs.dll");
PWICConvertBitmapSource pFunc =
(PWICConvertBitmapSource)GetProcAddress(hDll, "WICConvertBitmapSource");
printf("WICConvertBitmapSource: 0x%p.\n", pFunc);
pFunc(NULL, NULL, NULL);
FreeLibrary(hDll);
#else
WICConvertBitmapSource(NULL, NULL, NULL);
#endif
return 0;
}
When built by gcc test.c -DLOAD_FROM_DEF, the program prints address of the function and terminates correctly. Although, when linked against the import library from the following def:
LIBRARY WindowsCodecs.dll
EXPORTS
WICConvertBitmapSource#12
, this error pops out:
The procedure entry point WICConvertBitmapSource#12 could
not be located in the dynamic link library WindowsCodecs.dll.
Surprisingly enough, if I remove the declaration of WICConvertBitmapSource from the source and #12 from def file, the program links and runs fine.
How can I create a correct import library?
Notes: I'm running MinGW on Windows 7 SP1. My gcc version is 4.7.0 with w32api 3.17 installed. The problem appears with many functions, like GdiAlphaBlend, or SHCreateStreamOnFileEx.
The import library should've been created with --kill-at flag, like this:
dlltool --kill-at -D WindowsCodecs.dll -d WindowsCodecs.def -l libwindowscodecs.a
This article clarified everything for me: http://wyw.dcweb.cn/stdcall.htm

Resources