win32 Api programming - c++

I want to get a running application text e.g if i am running notepad then i want to get the text written inside it .For this first i have to get the handle of notepad but i don't know how to get the notepad handle so please tell me .Then through which functions i can get its inside text ? which header files to include ? what are necessary declarations?
Please help me i am new to windows API programming.i have gone through basic tutorials of windows programming but that doesn't help me a lot.

Use FindWindowEx. Though you must have been able to find this yourself, if you were looking/googling for a way to "find notepad handle in C++" ;)
You can even find complete examples on "Sending text to notepad in C++"

To expand on GolezTrol's answer, you could do this:
#include <windows.h>
#include <tchar.h>
int CALLBACK _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow ) {
HWND hwnd = FindWindow( _T("Notepad"), NULL);
hwnd = FindWindowEx( hwnd, NULL, _T("edit"), NULL );
TCHAR lpText[256];
SendMessage( hwnd, WM_GETTEXT, _countof(lpText), (LPARAM)lpText);
MessageBox(0, lpText, lpText, 0);
return ERROR_SUCCESS;
}
In reality, you would probably use a more reliable method of window identification (eg. enumerating all windows and verifying what process it belongs to)

Related

C++ : Why this window title gets truncated?

Visual C++ 2012 RC, Win7
Chinese simplified
Project Properties > use multi byte character set
When I run this program, the window's title shows a single letter "S", not a whole word "Sample".
#pragma comment(linker, "/SubSystem:Windows")
#include <windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, int) {
WNDCLASSW wc = { 0 };
wc.style = CS_VREDRAW | CS_HREDRAW;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
wc.hbrBackground = reinterpret_cast<HBRUSH>(GetStockObject(WHITE_BRUSH));
wc.lpszClassName = L"MyWindowClass";
wc.lpfnWndProc = [](HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
if (uMsg - WM_DESTROY)
return DefWindowProc(hWnd, uMsg, wParam, lParam);
else {
PostQuitMessage(0);
return HRESULT();
}
};
RegisterClassW(&wc);
CreateWindowExW(0, L"MyWindowClass", L"Sample",
WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, SW_SHOW, CW_USEDEFAULT, 0,
nullptr, nullptr, hInstance, nullptr);
for (MSG msg; GetMessage(&msg, nullptr, 0, 0); DispatchMessage(&msg));
}
If I use Unicode (Project Properties), keep source code unchanged, window title shows "Sample", looks correct.
If I use multi byte, in source code I use WNDCLASS = { ..., "MyWindowClass" } and RegisterClassA, keep CreateWindowExW unchanged, window title shows word "Sample", looks correct.
If I use multi byte, in source code I use CreateWindowExA("MyWindowClass", "Sample"), keep WNDCLASSW and RegisterClassW unchanged, window title shows letter "S".
What makes it show a single "S", am I doing something wrong?
Append
If I keep all unchanged, that is, use multi byte, use code shown above, window title shows letter "S".
(If you run this program and see "Sample" on window title, rather than "S", then it's more likely a specific problem on chs version of vc++ 2012 (or OS)).
The problem in your code is that you are using DefWindowProc instead of DefWindowProcW. Changing that will fix the code.
Ideally you should change your project settings to use Unicode, not multi-byte character set. This will simplify everything and you can use the macros like CreateWindowEx and RegisterClassEx instead of explicitly using the Unicode / ANSI versions as you are.
As others have said, this is a mismatch between character sets.
You should ideally match character sets between all your API calls that interact with each other. So if you use CreateWindowExW you should also use RegisterClassExW, DefWindowProcW, DispatchMessageW...
This is a very nice one, learned something new!
You need to change
return DefWindowProc(hWnd, uMsg, wParam, lParam);
to
if(IsWindowUnicode(hWnd))
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
else
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
Or even better: stick to one character encoding. At best just use RegisterClass, CreateWindowEx and so on and let the compiler take the right Unicode or ANSI function.
CreateWindowExA interprets the string as 8 bit characters. The second 8 bits of L"Sample" is zero, because its first character is 0x0053 - the L means use wide characters. So the function interprets that as a 1 character null terminated string.
I think the msdn page for RegisterClass hints at the reason for the failure here, in the remarks section it mentions how that if you use either wide character or ansi support, then it will pass internal text paramaters/message in this format (wide char/ansi). Quite possibly that's what's happening with the window title, even though we're saying use CreateWindowExA, this doesn't work as internally the Windows SDK has encoded that string as a wide character string, and the CreateWinowExA tries to output as if it was an Ansi string.
In short don't go mixing the W and A methods, unless you've a good reason for doing so, and let windows headers take care of it for you, if you want wide char support define your UNICODE macro.
In your last case your L"Sample" still remains Unicode, isn't it? You can use _T() macro, which automatically adds or removes L prefix depending on Unuicode setting of the project.
And Unicode L"Sample", as #Pete have already said, is "S\0..." in ascii, that's why only one symbol is printed.
I'm glad I found this. I was looking all over for an answer, and it seems rather difficult to find correctly with Google etc. I did find similar problems reported for specific programs, always blaming "some plug in".
It is maddening because the problem with the WndProc is nowhere near the call to CreateWindowEx nor RegisterClassEx!
BTW, I use -W suffixes explicitly, because I want to make one DLL that works for programs built either way, or overcome the non-Unicode settings of the program I'm adding to.

Embed /Load a DLL as a resource in VC++ 2008?

As the topic's description/title puts it, is this a possibility because I've been searching around on Google and other sources and without any luck I've come here to ask the question...
Is it at all possible to Embed a DLL as a resource into my final Executable and then call upon it/ as-if it were an external file in the current directory and/or System Directory?
I've tried a number of things without luck, a number of said solutions are not working out so well, I've seemingly embedded the DLL with my .rc file, however am struck with the problem of trying to call upon it, perhaps it's needing to be saved into a physical file on the disk, I'm not sure.
[EDIT]
Below is currently the code I've implemented, still without any success; I am still confronted with The program can't start because soandso.dll is missing from your computer.
Code below, -/
int WINAPI WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
HRSRC hRes = FindResource( hInstance, MAKEINTRESOURCE("#101"), "IDR_DLLRESOURCE_101" );
HGLOBAL hData = LoadResource( hInstance, hRes );
LPVOID lpFile = LockResource( hData );
DWORD dwSize = SizeofResource( hInstance, hRes );
HANDLE hFile = CreateFile("soandso.dll", GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
HANDLE hFilemap = CreateFileMapping(hFile, 0, PAGE_READWRITE, 0, dwSize, 0);
LPVOID lpBaseAddr = MapViewOfFile(hFilemap, FILE_MAP_WRITE, 0, 0, 0);
CopyMemory(lpBaseAddr, lpFile, dwSize);
UnmapViewOfFile(lpBaseAddr);
CloseHandle(hFilemap);
CloseHandle(hFile);
return 0;
}
Thank you in advance for any and all help provided.
It is fundamentally incompatible with the way Windows treats executable code in a PE32 file format. It must be present in a file, Windows creates a memory-mapped file to map it into memory. Trying anything like loading it into memory from a resource requires you taking over all of the duties of the Windows loader. Which includes relocating the code if it cannot be located at the expected base address, finding and loading all of the dependent DLLs and calling their DllMain() methods.
Particularly the DLL_THREAD_ATTACH and DETACH notifications are next to impossible to implement yourself since you can't control every thread that gets created. Very hard to do right and there's not a single winapi that will help you doing this. It is not worth it. And most certainly not competitive with just linking the DLL's code into your EXE image.
The only supported way to load a DLL is from a file. So, when you need to load this DLL, extract the resource, save it to a file (e.g. in the temporary directory), and call LoadLibrary and GetProcAddress to link to the library.

C++ WIN32: Running a program without a command prompt window

I have written a program which triggers a relay switch on a serial port. The relay is closed for 10ms, after which the program closes. However, the program insists on running in a small command prompt window. I would like the program to run without stealing focus; either by running in the background or, even better, without opening a window at all.
Here is the complete program:
#include <windows.h>
//Initialise Windows module
int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance,
LPSTR lpszArgument, int nFunsterStil)
{
//Define the serial port precedure
HANDLE hSerial;
//Open the port
hSerial = CreateFile("COM1",GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
//Switch on relay
EscapeCommFunction(hSerial, SETDTR);
//Wait 10ms
Sleep(10);
//Switch off relay
EscapeCommFunction(hSerial, CLRDTR);
//Close the port
CloseHandle(hSerial);
//End with error code 0
return 0;
}
What must I change in order to prevent it running in a window?
Try adding #pragma comment(linker, "/SUBSYSTEM:WINDOWS")
If that does not work try to hide the window manually:
HWND hWnd = GetConsoleWindow();
ShowWindow( hWnd, SW_HIDE );
What type of project did you create? If you selected console application, the compiler is doing it. Make an empty Win32 application with the above source. No window should be created. If it is, consider how you're launching the application (start, cmd /c, etc)

Windows API - Beginner help

I try to create a very simple app using windows API.
I've done some small apps in console. This is the first time I do with Win32 apps.
I've searched and found a document from forgers which is recommended in this site. But I try to write very first line:
#include <stdafx.h>
#include <windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MessageBoxW(NULL, "Good bye Cruel World", "Note", MB_OK);
return 0;
}
But it doesn't work (erased lines from default project created by VS 2008 and write these lines).
There are two versions of most windows API calls, one which takes single byte string and one which takes 2 byte unicode strings. The single byte one has an A on the end of the name and the 2 byte one has a W. There are macros defined in windows.h so that if you leave the letter out it picks one or the other depending on compiler macros.
In your code you write -
MessageBoxW (NULL, "Good bye Cruel World", "Note", MB_OK );
You are calling the wide character version of the API with single byte strings which won't work. Either change to MessageBoxA or change your strings to wide strings -
MessageBoxW (NULL, L"Good bye Cruel World", L"Note", MB_OK );
Remove the first line. What remains is a valid Windows program, which should compile under any IDE. Your problem is the stdafx.h header which is an artefact of VS, and you may have other problems if you try to "reuse" an existing VS project. If you want to nkow how compilation really works, it's a good idea to build some simple apps not using an IDE, but a command line compiler like MinGW.
And in future, post what error messages you are getting using copy and paste.
You need at least a message loop to run, in order for the application to process messages:
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
There are many tutorials on the message loop on the web, such as here:
http://www.winprog.org/tutorial/message_loop.html
If you're just starting GUI programming, you're best off reading a book, and working through the examples. Petzold is a classic. Learning programming by collecting snippets of partially working code cribbed from random web pages is going to be time-consuming, difficult and patchy. A well-written book will lead you through the fundamentals and explain things in stages. Have fun!

Create an Application without a Window

How would you program a C/C++ application that could run without opening a window or console?
When you write a WinMain program, you automatically get the /SUBSYSTEM option to be windows in the compiler. (Assuming you use Visual Studio). For any other compiler a similar option might be present but the flag name might be different.
This causes the compiler to create an entry in the executable file format (PE format) that marks the executable as a windows executable.
Once this information is present in the executable, the system loader that starts the program will treat your binary as a windows executable and not a console program and therefore it does not cause console windows to automatically open when it runs.
But a windows program need not create any windows if it need not want to, much like all those programs and services that you see running in the taskbar, but do not see any corresponding windows for them. This can also happen if you create a window but opt not to show it.
All you need to do, to achieve all this is,
#include <Windows.h>
int WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int cmdShow)
{
/* do your stuff here. If you return from this function the program ends */
}
The reason you require a WinMain itself is that once you mark the subsystem as Windows, the linker assumes that your entry point function (which is called after the program loads and the C Run TIme library initializes) will be WinMain and not main. If you do not provide a WinMain in such a program you will get an un-resolved symbol error during the linking process.
In windows:
#include <windows.h>
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
// <-- Program logic here
return 0;
}
Be sure to use the /SUBSYSTEM linker switch as mentioned by Adam Mitz.
On other platforms:
int main(int argc, char**argv)
{
// <-- Program logic here
return 0;
}
If you have a need to contiguously run your program without having console or window you might find useful deamon on *NIX or services on Windows, this .NET example if you need plain win32 just google a little bit for sample.
Since your question tagged as win32 i assume that services are more relevant for you.
This also processes messages:
#include <windows.h>
#include <stdio.h>
int CALLBACK WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
MSG msg;
DWORD curThreadId;
curThreadId = GetCurrentThreadId();
// Send messages to self:
PostThreadMessage(curThreadId, WM_USER, 1, 2);
PostThreadMessage(curThreadId, WM_USER+1, 3, 4);
PostThreadMessage(curThreadId, WM_USER+2, 5, 6);
PostThreadMessage(curThreadId, WM_USER+3, 7, 8);
PostThreadMessage(curThreadId, WM_QUIT, 9, 10);
while (GetMessage(&msg, NULL, 0, 0)) {
printf("message: %d; wParam: %d; lParam: %d\n", msg.message, msg.wParam, msg.lParam);
}
return (int) msg.wParam;
}
In Visual Studio Express 2010 after setting the subsystem to windows (as suggested by user17224), alternatively to changing the main to WinMain (as suggested by user17224 and Brian R. Bondy), one can set the entry function to main in properties, linker, advanced, entry point: just type main in the text box.
Use Visual Studio wizard to create the Win32 Application. But don't create the window i.e., you remove the window creation function.
Alternatively we can create Win Service application.
If you are using MSVC or Visual Studio just use the new Project Wizard and select the Console Application.