Cannot assign lpCmdLine parameter to a char* pointer - c++

This code check run application this param:
INT APIENTRY _tWinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPTSTR lpCmdLine, INT iShow)
{
char* szCmdLine = lpCmdLine;
...
}
Error this lines : error C2440: 'initializing' cannot convert from 'LPTSTR' to 'char *'

Its because LPTSTR could be LPSTR or LPWSTR considening project UNICODE settings. When unicode is enabled application use LPWSTR, if not LPSTR.
LPSTR is just an alias for char*. LPWSTR - wchar_t*. T in LPTSTR mean TCHAR type which defenition can be char or wchar_t whatever UNICODE or _UNICODE symbol is defined in your project.
LP means "long pointer", long is 32 bit memory address. STR - string.
So lets describe LPSTR - "long pointer to ANSI string"; LPWSTR - "long pointer to wide character string" and LPTSTR - "long pointer to TCHAR string".
To W or T letter can be added prefix C like LPCSTR, LPCTSTR, LPCWSTR wich means that these pointers are constant like const char* or const wchar_t*.
So your code must look like:
INT APIENTRY _tWinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPTSTR lpCmdLine, INT iShow)
{
TCHAR* szCmdLine = lpCmdLine;
...
}
or
INT APIENTRY _tWinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPTSTR lpCmdLine, INT iShow)
{
LPTSTR szCmdLine = lpCmdLine;
...
}

Related

How to interpret docs on WinMain?

Please look at the WinMain docs.
int __clrcall WinMain(
[in] HINSTANCE hInstance,
[in] HINSTANCE hPrevInstance,
[in] LPSTR lpCmdLine,
[in] int nShowCmd
);
How should I interpret this? Is in attribute optional which is denoted by the square brackets? If so, what does it look like.
I tried to compile a simple application in Visual Studio with the following flags:
/clr /permissive- /Zc:twoPhase-
#include <Windows.h>
int __clrcall WinMain(
[in] HINSTANCE hInstance,
[in] HINSTANCE hPrevInstance,
[in] LPSTR lpCmdLine,
[in] int nShowCmd
) {
return 0;
}
But it won't compile and gives the following errors.
C2373 WinMain': redefinition; different type modifiers
C2337 'in': attribute not found
E0337 linkage specification is incompatible with previous "WinMain" (declared at line 1033) WinBase.h
E0147 declaration is incompatible with "int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)" (declared at WinBase.h)
The [in] decorations are just for documentation. You can ignore them and just implement WinMain like in the sample WinMain docs:
If building for Multibyte (a.k.a. ANSI):
#include <Windows.h>
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, LPSTR cmdline, int cmdshow)
{
return MessageBoxA(nullptr, "hello, world", "caption", 0);
}
If building for Unicode:
#include <Windows.h>
int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE hInstPrev, LPWSTR cmdline, int cmdshow)
{
return MessageBoxW(nullptr, L"hello, world", L"caption", 0);
}

How to execute a method of a dll (C++) with parameters with command prompt

I created a dll(in c++) with one method called "changeSize"(in kb) which has the argument "size". So the method basically sets a new size of a file (the file that is stated in the method).
Now I want to execute the method of this dll in command prompt.
I've tried to execute the method with the help of "rundll32.exe", so i executed that command in command prompt, but it does not work:
rundll32.exe ChangeSize.dll,changeSize 1024
Question 1: Is it possible to execute a method of a dll with "rundll32.exe" if it needs arguments, or is there a simple way to do it with command prompt or if necessary powershell?
EDIT
Now I know that the dll needs to have a special signature, that it is able to be executed with "rundll32.exe".
I have come accross this: https://stackoverflow.com/a/11913860/16104144, which is a short documentation on how to create a dll that can be run with "rundll32.exe".
I have the following code, and when i set the parameter "size" OF MY CODE to any value and build the dll and run it in cmd:
rundll32.exe ChangeSize.dll,EntryPoint, then it works, but I want to be able to define the size just when i execute the dll with "rundll32.exe" and i don't want to have to define a size before building the dll.
Question 2: Where do i have to add the variable size in my code that "rundll32.exe" knows that the dll needs that argument. The parameter "size" should be "unsigned long int".
So this is my code in the main file(dllmain.cpp):
#include "pch.h"
namespace fs = std::filesystem;
__declspec(dllexport) void CALLBACK EntryPoint(
HWND hwnd,
HINSTANCE hinst,
LPSTR lpszCmdLine,
int nCmdShow
);
void CALLBACK EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
{
fs::path p = "C:\\Users\\myname\\AppData\\Local\\Temp\\1304.txt";
fs::resize_file(p, size);
int msgboxID = MessageBox(
NULL,
L"Hello World from Run32dll",
L"HelloWorld",
MB_ICONWARNING | MB_CANCELTRYCONTINUE | MB_DEFBUTTON2
);
switch (msgboxID)
{
case IDCANCEL:
break;
case IDTRYAGAIN:
break;
case IDCONTINUE:
break;
}
}
Adding the variable to the function and its declaration did not work:
void CALLBACK EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow, unsigned long int size`, unsigned long int size);
As it says here https://learn.microsoft.com/en-us/windows/win32/learnwin32/winmain--the-application-entry-point, the arguments that are passed with this command:
rundll32.exe ChangeSize,changeSize 1024
are saved inside the variable
LPSTR lpszCmdLine
And because it is just one argument I can just replace the variable "size" with (unsigned long int)lpszCmdLine:
#include "pch.h"
namespace fs = std::filesystem;
__declspec(dllexport) void CALLBACK EntryPoint(
HWND hwnd,
HINSTANCE hinst,
LPSTR lpszCmdLine,
int nCmdShow
);
void CALLBACK EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
{
fs::path p = "C:\\Users\\myname\\AppData\\Local\\Temp\\1304.txt";
fs::resize_file(p, (unsigned long int)argument;
/*int msgboxID = MessageBox(
NULL,
L"Hello World from Run32dll",
L"HelloWorld",
MB_ICONWARNING | MB_CANCELTRYCONTINUE | MB_DEFBUTTON2
);
switch (msgboxID)
{
case IDCANCEL:
break;
case IDTRYAGAIN:
break;
case IDCONTINUE:
break;
}/*
}
___________________________________________________________________________
I have to admit that it's pretty new to me to create *dlls*, but i can not find anything about creating *dlls* with parameters that can be run with "rundll32.exe" and I am very thankful for you even reading this.
Question 1: First of all, not every .dll can be executed with rundll32.exe, because the .dlls need a special signature, so a special structure. For example is an EntryPoint necessary.
Here it says how the structure looks like:
https://stackoverflow.com/a/11913860/16104144
Question 2: The arguments are stored in LPSTR lpszCmdLine and what the other variables save that are in the declaration of the method:
void CALLBACK EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
can be seen here:
https://learn.microsoft.com/en-us/windows/win32/learnwin32/winmain--the-application-entry-point
Just use the variable lpszCmdLine as the variable that you need. But as soon as you have more than one argument so e.g. rundll32.exe ChangeSize,changeSize 1 9 you need to split it.

Winrt Message Dialog not showing

I am trying to display a Message Dialog in C++ (winrt) from a Desktop Windows App targeting Win 10 x64. The following code executes but the dialog is not shown. Return code from ShowAsync is good
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
Microsoft::WRL::Wrappers::RoInitializeWrapper init(RO_INIT_SINGLETHREADED);
Microsoft::WRL::ComPtr<ABI::Windows::UI::Popups::IMessageDialogFactory> messageDialogFactory;
Microsoft::WRL::Wrappers::HStringReference messageDialogFactoryId(RuntimeClass_Windows_UI_Popups_MessageDialog);
Windows::Foundation::GetActivationFactory(messageDialogFactoryId.Get(), messageDialogFactory.GetAddressOf());
Microsoft::WRL::ComPtr<ABI::Windows::UI::Popups::IMessageDialog> messageDialog;
Microsoft::WRL::ComPtr<ABI::Windows::Foundation::Collections::IVector<ABI::Windows::UI::Popups::IUICommand*>> uiCommands;
messageDialogFactory->CreateWithTitle(Microsoft::WRL::Wrappers::HStringReference(L"XXX").Get(), Microsoft::WRL::Wrappers::HStringReference(L"YYY").Get(), messageDialog.GetAddressOf());
messageDialog->get_Commands(uiCommands.GetAddressOf());
Microsoft::WRL::ComPtr<ABI::Windows::UI::Popups::IUICommandFactory> uiCommandFactory;
Microsoft::WRL::Wrappers::HStringReference commandFactoryId(RuntimeClass_Windows_UI_Popups_UICommand);
Windows::Foundation::GetActivationFactory(commandFactoryId.Get(), uiCommandFactory.GetAddressOf());
w::ComPtr<pu::IUICommand> button;
uiCommandFactory->CreateWithHandler(Microsoft::WRL::Wrappers::HStringReference(L"ZZZ").Get(), new ButtonHandler(), button.GetAddressOf());
uiCommands->Append(button.Get());
Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncOperation<ABI::Windows::UI::Popups::IUICommand*>> showOperation;
HRESULT hr = messageDialog->ShowAsync(showOperation.GetAddressOf());
MSG msg;
while( ::GetMessage(&msg, 0, 0, 0) > 0 )
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
return 0;
}
Should have read documentation - API doesn't have the DualApiPartitionAttribute

How to set the window's default position?

I'm using Dev C++. After I created a windows application, it generated some code which creates a window. I understand the code broadly. I've found the code to set the size, title, and background color but how do I set up the default position of the new window? I want to start it at the center of the screen.
You should have CreateWindow function, its definition is as follows:
HWND WINAPI CreateWindow(
__in_opt LPCTSTR lpClassName,
__in_opt LPCTSTR lpWindowName,
__in DWORD dwStyle,
__in int x,
__in int y,
__in int nWidth,
__in int nHeight,
__in_opt HWND hWndParent,
__in_opt HMENU hMenu,
__in_opt HINSTANCE hInstance,
__in_opt LPVOID lpParam
);
The x and y parameters specify the location of the newly-created window. These are the ones you need to set.

Why do we need to pass LPCTSTR lpParameters with ShellExecute

Shell Execute has the following signature :
HINSTANCE ShellExecute(
__in_opt HWND hwnd,
__in_opt LPCTSTR lpOperation,
__in LPCTSTR lpFile,
__in_opt LPCTSTR lpParameters,
__in_opt LPCTSTR lpDirectory,
__in INT nShowCmd
);
How can we use lpParameters , Can we handle the parameter in my application. I am executing my app as below:
HINSTANCE hShellExecuteStatus = ShellExecute(NULL, "open", "MyPath/MyApp.EXE", NULL, NULL, SW_SHOWNORMAL);
Can I pass something in the 4th parameter i.e: lpParameters , so that I can handle this with MyApp.Exe , let's say if I am passing "Hi: in the 4th param:
HINSTANCE hShellExecuteStatus = ShellExecute(NULL, "open", "MyPath/MyApp.EXE", "Hi", NULL, SW_SHOWNORMAL);
Can I check in my application whether it is hi and display a message high.
I tried with POSTMESSAGE , but is not helpful with shellexecute
lpParameters will come through in the command line. Use GetCommandLine() to see it.