I need to write a program in C++ that queries the OS for running Windows, find a Window with a specific window title, and return the Native Window Handle value as a String.
So far, I've figured out everything but the last part. I'm not too familiar with C++, as I'm writing this for a JS project as a NodeJS C++ addon, so I'd appreciate any help.
Here's the program so far:
static BOOL CALLBACK enumWindowCallback(HWND hWnd, LPARAM lparam) {
int length = GetWindowTextLength(hWnd);
char* buffer = new char[length + 1];
GetWindowText(hWnd, buffer, length + 1);
std::string windowTitle(buffer);
if (IsWindowVisible(hWnd) && length != 0) {
std::cout << hWnd << ": " << windowTitle << std::endl;
if (windowTitle.compare("Find This Window") == 0) {
// Here is the confusion. I've found the right HWND, but I don't know how to cast the HWND to a String
return FALSE;
}
}
return TRUE;
}
int::main() {
EnumWindows(enumWindowCallback, NULL);
}
On this line: std::cout << hWnd << ": " << windowTitle << std::endl;, the hWnd returns the hexadecimal value that I want. For example, it prints out: 0000000000100566: Find this App
The value preceding the : is the value I want to return as a String, but I can't figure out how. I've tried casting it, but it doesn't work.
Again, this is probably a simple solution, but I can't find it on the internet and my limited knowledge of C++ is hindering me.
Actually, the question is how to convert number to string.
At the beginning, as #KenWhite said, HWND is an opaque value.
#include <Windows.h>
#include <sstream>
void main()
{
HWND i = FindWindow(NULL,NULL);
char buffer[sizeof(HWND) * 2 + 1]{};
_itoa_s((int)i, buffer, 16);
std::ostringstream Convert;
Convert << std::hex << i;
}
Related
I am trying to get the various attributes of a file as seen in its "Details" tab with the WinAPI function VerQueryValue. I have successfully used this function to get the non-string version info with VS_FIXEDFILEINFO, but have not been able to get the example shown at the bottom of the functions documentation working.
The example isn't actually complete as it leaves out the use of the other related functions and the constructions of some buffers needed to use the function, so I've filled in the blanks the best I can and changed some of the in-between steps to use C++ SL since that's ultimately the language I need to use this in:
#include <iostream>
#include <iomanip>
#include "sstream"
#include "Windows.h"
#pragma comment(lib, "Version.lib")
int ReadOutFileDescriptions(std::wstring filename)
{
LPBYTE lpBuffer = NULL;
DWORD verHandle, verSize = GetFileVersionInfoSize(filename.c_str(), &verHandle);
if (verSize != NULL)
{
LPSTR verData = new char[verSize];
if (GetFileVersionInfo(filename.c_str(), verHandle, verSize, verData))
{
UINT cbTranslate;
// Structure used to store enumerated languages and code pages.
struct LANGANDCODEPAGE {
WORD wLanguage;
WORD wCodePage;
} *lpTranslate;
// Read the list of languages and code pages.
VerQueryValue(verData, TEXT("\\VarFileInfo\\Translation"), (LPVOID*)&lpTranslate, &cbTranslate);
// Read the file description for each language and code page.
for (ULONGLONG i = 0; i < (cbTranslate / sizeof(struct LANGANDCODEPAGE)); i++)
{
std::wostringstream ss; ss << std::setfill(L'0') << std::hex;
ss << std::setw(4) << lpTranslate[i].wLanguage;
std::wstring langS = ss.str();
ss.str(std::wstring());
ss << std::setw(4) << lpTranslate[i].wCodePage;
std::wstring codeS = ss.str();
std::wstring subBlock = L"\\StringFileInfo\\" + langS + codeS + L"\\FileDescription";
// Retrieve file description for language and code page "i".
WCHAR descBuffer[50];
LPVOID lpBuffer = &descBuffer;
UINT bufferSize;
VerQueryValue(verData, subBlock.c_str(), &lpBuffer, &bufferSize);
std::cout << bufferSize << '\n' << descBuffer;
}
}
delete[] verData;
}
return 0;
}
int main(int argc, char* argv[])
{
ReadOutFileDescriptions(L"MyFile.exe");
return 0;
}
I only have a little experience with WinAPI and its typedefs and my C is a bit rusty so I'm sure I'm just setting-up/using a buffer incorrectly or the like.
The printed buffer size is correct (the length of MyFile.exe's description + 1 for the null character) so I know the function is getting the right value, but the actually value that gets printed is just a series of hexadecimal character, most likely an address.
What am I doing wrong?
EDIT (Answer):
Thanks to #dxiv I was made aware that I did not fully understand how the "result" argument (lplpBuffer) of VerQueryValue was to be used, both internally and after the function returns.
Changing the end of the loop to the following achieves my desired result:
//WCHAR descBuffer[50] Not required, the function doesn't utilize a user made buffer
LPVOID lpBuffer;
UINT bufferSize;
VerQueryValue(verData, subBlock.c_str(), &lpBuffer, &bufferSize); // lpBuffer is reassigned here
std::wstring fileDescription((const TCHAR*)lpBuffer); // Create std::string from C style string (char*) that lpBuffer now points to
std::wcout << bufferSize << '\n' << fileDescription;
VerQueryValue(verData, subBlock.c_str(), &lpBuffer, &bufferSize);
std::cout << bufferSize << '\n' << descBuffer;
Once VerQueryValue returns, lpBuffer no longer points to descBuffer, but to a different buffer assigned inside the call. The returned string is at (const TCHAR *)lpBuffer at that point.
Hello im new to coding and im trying to write processes memory in C++ using a Calculator as an example. I cant seem to find why this is giving me a error at the memory address.
#include <iostream>
#include <windows.h>
//Findwindow();
//GetWindowThreadProcessId();
//OpenProcess();
//WriteProcessMemory();
//CloseHandle();
using namespace std;
int main() {
int newValue = 189;
HWND hWnd = FindWindow(0, "Calculator");
if (hWnd == 0) {
cerr << "Cannot find window." << endl;
}
else {
DWORD pId;
GetWindowThreadProcessId(hWnd, &pId);
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pId);
if (!hProc) {
cerr << "Cannot Open Process" << endl;
}
else {
int isSuccessful = WriteProcessMemory(hProc, (LPVOID)25D09ED227C, &newValue, (DWORD)sizeof(newValue), NULL);
}
}
Your problem is you're passing an integer that contains letters as a pointer:
WriteProcessMemory(hProc, (LPVOID)25D09ED227C, &newValue, (DWORD)sizeof(newValue), NULL);
25D09ED227C is an integer literal but you've included characters from a hexadecimal number.
Just put a 0x in front to tell the compiler it's in hex.
using 0x25D09ED227C will fix your problem
You can also remove the (DWORD) from the fourth argument also
Can someone please tell me the problems with this piece of code?
I'm bulding a windows app, not a console. Am I using the functions
correctly. What types should I used? Okay I fixed semicolon err and
else err? Still not working properly.
#include <windows.h>
int WINAPI WinMain(HINSTANCE thisin,HINSTANCE previn,LPSTR lpstr,INT int_)
{
LPTSTR buffer;
DWORD size;
SetConsoleTitle("Console Title");
if(!GetConsoleTitle(buffer,size))
cout << "error" << endl;
else cout << *buffer << endl;
system("Pause");
return 0;
}
It have 2 problems, first a ';' at end of if that is a C++ mistyping error and every body say it, but second is: for every API that get a buffer to return something, you should provide a valid buffer. Assume GetConsoleTitle implemented as:
BOOL GetConsoleTitle(LPTSTR p, DWORD dwSize)
{
LPTSTR actualTitle = /* Get actual title from somewhere */;
while (dwSize--)
{
*p++ = *actualTitle++;
if (!*p++) return TRUE;
}
// Not enough buffer
return FALSE;
}
Now look at your program, you pass an uninitialized LPTSTR to the function and as soon as API call *p++ = *actualTitle++, it will cause a segmentation fault or Access violation.
so in order to solve it, you must pass a valid buffer as first argument and since LPTSTR is a typedef of TCHAR* you should have:
const DWORD dwSize = 128;
TCHAR buffer[dwSize];
if (GetConsoleTitle(buffer, dwSize)) std::cout << "OK!" << std::endl;
First thing is first. Your statement prints whether there is an error or not. Use an else there:
if(!GetConsoleTitle(buffer,size))
cout << "error" << endl;
else
cout << *buffer << endl;
and the ; after your if was a typo, I corrected it above.
You are using API's for Console App. Create a console app, copy this code to console project c or cpp source file and replace
int WINAPI WinMain(HINSTANCE thisin,HINSTANCE previn,LPSTR lpstr,INT int_)
with
int _tmain(int argc, char *argv[])
also remove ';' (semicolon) from 'if' statement.
Okay, I want to delete my app from Applications list in Windows task maneger. I found the following code code:
http://www.codeproject.com/KB/system/Hack_Windows_Task_Manager.aspx
I wanted to do it in C/C++ so I code this:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <iostream>
BOOL CALLBACK Usun(HWND hwnd,LPARAM lParam);
int main()
{
HWND hwnd;
while (true)
{
hwnd = FindWindow(NULL,"Menedżer zadań Windows"); //<-- it's in polish and it is finding window without problems
if (hwnd == NULL) std::cout << "Not found" << std::endl;
else
{
std::cout << "Found" << std::endl;
EnumChildWindows(hwnd,Usun,NULL);
Sleep(500);
}
}
std::cin.get();
return 0;
}
BOOL CALLBACK Usun(HWND hwnd,LPARAM lParam)
{
char zakladka[256] = {0};
GetWindowText(hwnd,zakladka,256);
char lista[256] = {0};
GetClassName(hwnd,lista,256);
if ((strcmp(zakladka,"Aplikacje") == 0) && (strcmp(lista,"SysListView32") == 0))
{ //Aplikacje is the same as Tasks
std::cout << "Found SysList" << std::endl;
}
return TRUE;
}
But the program is not working they way it should.
IMPORTANT: IT'S NOT MEANT TO BE SOME VIRUS PROGRAM
I think you should also hide your app from task bar. Check this http://www.codeproject.com/KB/dialog/hidetaskbar.aspx
I've been trying to write an application, using Qt and mingw32, to download images and set them as the background Wallpaper. I have read several articles online about how to do this, in VB and C#, and to some extent how to do it in c++. I am currently calling the SystemParametersInfo with what seems to be all the correct arguments (no compiler errors) and it fails. No great crash of cymbals, just a 0 returned. GetLastError() returns an equally enlightening 0.
Below is the code I am using (In a slightly modified form, so you do not have to view the object internals).
#include <windows.h>
#include <iostream>
#include <QString>
void setWall()
{
QString filepath = "C:\\Documents and Settings\\Owner\\My Documents\\Wallpapers\\wallpaper.png";
char path[150];
strcpy(path, currentFilePath.toStdString().c_str());
char *pathp;
pathp = path;
cout << path;
int result;
result = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, pathp, SPIF_UPDATEINIFILE);
if (result)
{
cout << "Wallpaper set";
}
else
{
cout << "Wallpaper not set";
cout << "SPI returned" << result;
}
}
It could be that SystemParametersInfo is expecting an LPWSTR (a pointer to wchar_t).
Try this:
LPWSTR test = L"C:\\Documents and Settings\\Owner\\My Documents\\Wallpapers\\wallpaper.png";
result = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, test, SPIF_UPDATEINIFILE);
If this works (try it with a few different files just to make sure), you'll need to convert your char * to a LPWSTR. I'm not sure if Qt offers these services, but one function that may help is MultiByteToWideChar.
"C:\Documents and Settings\Owner\My Documents\Wallpapers\wallpaper.png";
shouldn't this be:
"C:\\Documents and Settings\\Owner\\My Documents\\Wallpapers\\wallpaper.png";
You cn use SetTimer to trigger a change.
#define STRICT 1
#include <windows.h>
#include <iostream.h>
VOID CALLBACK TimerProc(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime)
{
LPWSTR wallpaper_file = L"C:\\Wallpapers\\wallpaper.png";
int return_value = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, wallpaper_file, SPIF_UPDATEINIFILE);
cout << "Programmatically change the desktop wallpaper periodically: " << dwTime << '\n';
cout.flush();
}
int main(int argc, char *argv[], char *envp[])
{
int Counter=0;
MSG Msg;
UINT TimerId = SetTimer(NULL, 0, 2000, &TimerProc); //2000 milliseconds
cout << "TimerId: " << TimerId << '\n';
if (!TimerId)
return 16;
while (GetMessage(&Msg, NULL, 0, 0))
{
++Counter;
if (Msg.message == WM_TIMER)
cout << "Counter: " << Counter << "; timer message\n";
else
cout << "Counter: " << Counter << "; message: " << Msg.message << '\n';
DispatchMessage(&Msg);
}
KillTimer(NULL, TimerId);
return 0;
}