PostMessage not working for WM_PASTE , mfc - c++

I have an application which has a button on Click of button am trying to paste the text already available to Notepad. My application gathers the text first and puts it on the clipboard(this is working perfectly fine), I am facing problem with the Paste part. Here is the code, Please let me know where am i going wrong.
CWnd *pCwnd = FindWindow(NULL, _T("Untitled - Notepad"));
HWND handle = pCwnd->GetSafeHwnd();
pCwnd->PostMessageA(WM_PASTE,0,0);
I am using Notepad to test it so the name is ("Untitled - Notepad").
Please help me. Thanks in advance.

I don't use MFC, but you can probably translate to what you need. The issue is you need to send the message to the edit control, not the main window.
#include <Windows.h>
#include <string>
#include <cstdlib>
int main()
{
const std::string data("This is some text from the clipboard.");
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, data.size() + 1);
std::memcpy(GlobalLock(hMem), data.c_str(), data.size() + 1);
GlobalUnlock(hMem);
OpenClipboard(NULL);
EmptyClipboard();
SetClipboardData(CF_TEXT, hMem);
CloseClipboard();
HWND mainWindow = FindWindow(NULL, "Untitled - Notepad");
HWND editWindow = FindWindowEx(mainWindow, NULL, "edit", NULL);
PostMessage(editWindow, WM_PASTE, 0, 0);
return 0;
}

Related

winapi - a standard way to retrieve text from running text editor

Is there a standard message that can be sent to a text editor window or a certain WinApi call, that will retrieve the contents of the currently edited text?
For example, to retrieve the current contents of a Notepad window. (assumed that the most up to date text wasn't yet written to a file)
I've tried retrieving the text via SendMessage using WM_GETTEXT, WM_GETTEXTLENGTH but I was able to retrieve the title text only.
In general no there is no standard message for this.
But Windows' Notepad has an "Edit" child which responds to WM_GETTEXT and WM_GETTEXTLENGTH - messages normally used to retrieve text from input controls.
Here's a PoC demonstrating the idea:
#include <iostream>
#include <vector>
#include <string.h>
#include <Windows.h>
BOOL CALLBACK enumProc(HWND hwnd, LPARAM) {
std::vector<char> buf(100);
GetClassNameA(hwnd, buf.data(), 100);
if (strcmp(buf.data(), "Notepad")) return TRUE;
hwnd = FindWindowEx(hwnd, NULL, "Edit", NULL);
if (!hwnd) return TRUE;
int textLength = SendMessageA(hwnd, WM_GETTEXTLENGTH, 0, 0) + 1;
if (textLength <= 0) return TRUE;
buf.resize(textLength);
SendMessage(hwnd, WM_GETTEXT, textLength, (LPARAM)buf.data());
std::cout << buf.data() << "\n";
return TRUE;
}
int main() {
EnumWindows(&enumProc, 0);
}
Works on Windows 10:

C++ WINAPI Button Clipboard - Copy action

I am a bit new to C++ but I know the basics and how to use it properly. I am just wondering how to copy to a clipboard in a windows application. I want 4 buttons to be able to copy a message when clicked and store it in clipboard. Here is the code for the button, the if statement is the action that is carried out when clicked:
case WM_CREATE:{
CreateWindow(TEXT("BUTTON"), TEXT("Copythistext"),
WS_CHILD | WS_VISIBLE,
12,60,10,20,
hwnd, (HMENU) ID_BUTTON, NULL, NULL
);
break;
}
case WM_COMMAND:{ //this is where the button performs it's task
if(LOWORD(wParam)== ID_BUTTON) {
//this is where the task goes
}
break;
}
Sequence of events:
void AddToClipboard(char* pszText)
{
int nStrLen = strlen(pszText);
HGLOBAL hMem = GlobalAlloc(nStrLen + 1, GMEM_SHARE);
char* pCopyTo = (char*) GlobalLock(hMem);
strcpy(pCopyTo, pszText);
GlobalUnlock(hMem);
OpenClipboard(NULL); // or HWND handle instead of NULL
EmptyClipboard();
SetClipboardData(CF_TEXT, hMem); // hMem is handle to memory allocated with GlobalAlloc
CloseClipboard();
}
For the hMem, you usually do a GlobalAlloc(), GlobalLock(), copy string to the pointer returned by GlobalLock(), then do a GlobalUnlock() on the handle
There is a curious way to send text from BUTTON to clipboard: via SetDlgItemText + WM_LBUTTONDBLCLK to STATIC with SS_NOTIFY (size of STATIC may be =0).

Output LRESULT to console

I'm trying to output text from Notepad window to console and it's always 0.
What I'm doing wrong?
int main()
{
HWND hwnd = (HWND)0x0031019C; // Window Handler of Notepad
char szBuf[4096];
HWND hwndEdit;
LRESULT result;
hwndEdit = FindWindowEx(hwnd, NULL, L"Edit", NULL); // Class for edit box
result = SendMessage(hwndEdit, WM_GETTEXT, sizeof(szBuf) / sizeof(szBuf[0]), (LPARAM)szBuf);
cout<<"Contents: \n"<<result;
cin.get();
return 0;
}
I tried print_f, but it outputs unreadable characters:
printf( "Contents: %s\n", result, szBuf );
It looks to me like you probably have a little bit of a mismatch happening.
Based on the L"Edit", you seem to be doing a Unicode build (otherwise, you'd get an error message about not being able to convert an wchar_t const[5] to LPCSTR, and the code wouldn't compile.
If you do a Unicode build, however, WM_GETTEXT is going to write Unicode data to your buffer, so you need to prepare for and use Unicode instead of narrow characters for your buffer.
For convenience, I've modified it a little to find Notepad instead of using a hard-coded Window handle.
#include <windows.h>
#include <stdio.h>
#define elements(b) (sizeof(b)/sizeof(b[0]))
int main() {
HWND hwnd; // Window Handler of Notepad
wchar_t buf[4096]={0};
HWND hwndEdit;
LRESULT result;
hwnd=FindWindowEx(NULL, NULL, L"Notepad", NULL);
hwndEdit=FindWindowEx(hwnd, NULL, L"Edit", NULL); // Class for edit box
result = SendMessage(hwndEdit, WM_GETTEXT, elements(buf), (LPARAM)buf);
printf("%S", buf);
return 0;
}
I built with:
cl /DUNICODE whatever.cpp user32.lib
Then I did a quick test that printed out exactly the text I'd typed into Notepad. To verify the result, I then edited the text in notepad, ran it again, and it printed out the modified text.

Strange GetWindowText(); error

I am trying to get the text of a textedit control in a dialog in my Win32 C++ Application.
I am using the following block of code to get that, and also to test it.
HWND hCarRegNo = GetDlgItem( hDlg, IDC_REGNUMBER );
if( hCarRegNo )
{
LPWSTR carRegNo = NULL;
GetWindowText(hCarRegNo, carRegNo, 20);
MessageBox(hDlg, carRegNo, _T("Test"), MB_OK);
}
The MessageBox output is an empty string.
Where is my mistake?
Not allocating any memory for carRegNo. Try this
WCHAR carRegNo[20];
GetWindowText(hCarRegNo, carRegNo, 20);
After some more research, I have solved the problem: instead of LPWSTR, I had to use TCHAR carRegNo[256] to make this work.
HWND hCarRegNo = GetDlgItem( hDlg, IDC_REGNUMBER );
if( hCarRegNo )
{
TCHAR carRegNo[256] = L"";
GetWindowText(hCarRegNo, carRegNo, 256);
MessageBox(hDlg, carRegNo, _T("Test"), MB_OK);
}

Get Desktop PIDL from Coordinates

I'm trying to create functionality of the shell context menus despite them being blocked by a group policy for no real reason. One thing this demands is which icon the user is actually right-clicking, or if they are just clicking the desktop. The same thing also applies to explorer windows, although the desktop is where I'm planning on starting.
So far I can get the context menu to show for a specific file with a literal path. I found a nice list of interfaces on msdn, but none of the desktop-related ones I could find had any way of getting the desktop item like this. The closest match I could find was IActiveDesktop::GetDesktopItem with going through every single item and seeing whether the position matches, and then assuming none were clicked if none match.
This approach brings up two new issues, though. Firstly, I'm not sure how to go through every icon. Secondly, I have no clue how to convert this to a PIDL.
Also, even if I got the icons working, how would I extend this to the shell context menu for just the desktop?
Here's the code I use for a specific file:
#define _WIN32_WINNT _WIN32_WINNT_WINXP //going to be using on XP, tested on 7
#include <windows.h> //main header
#include <shellapi.h> //shell headers
#include <shlobj.h>
#include "G:\programming\v1\winwrap.h" //used for the window to display menu on
LPCONTEXTMENU cm; //holds context menu
msgproc (rproc) //this is called when right mouse button is depressed on window
{
//This function shows the context menu of the program on this window
//hwnd() is the HWND of the window involved with the right click
HMENU hMenu = CreatePopupMenu();
DWORD Flags = CMF_EXPLORE;
cm->QueryContextMenu(hMenu, 0, 1, 0x7FFF, Flags);
POINT pt;
GetCursorPos(&pt);
int Cmd = TrackPopupMenu(hMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x, pt.y, 0, hwnd(), 0);
CMINVOKECOMMANDINFO ci;
if (Cmd)
{
ci.lpVerb = MAKEINTRESOURCE(Cmd - 1);
ci.lpParameters = "";
ci.lpDirectory = "";
ci.nShow = SW_SHOWNORMAL;
cm->InvokeCommand(&ci);
}
}
int main()
{
Window win; //create window for menu to go on, can be invisible, fullscreen later
win.addmsg (WM_RBUTTONUP, rproc); //handle message with previous function
WCHAR fname [MAX_PATH] = L"C:\\Users\\Chris\\Desktop\\context.exe"; //full path
WCHAR path [MAX_PATH] = L"C:\\Users\\Chris\\Desktop"; //path part
WCHAR name [MAX_PATH] = L"context.exe"; //filename part
LPSHELLFOLDER desktopFolder; //get desktop shell folder
SHGetDesktopFolder (&desktopFolder);
LPITEMIDLIST pidl; //tried using this for no icon by changing GetUIObjectOf to this pild to no avail
DWORD eaten;
desktopFolder->ParseDisplayName (0, 0, path, &eaten, &pidl, 0);
LPSHELLFOLDER parent;
desktopFolder->BindToObject (pidl, 0, IID_IShellFolder, (void **)&parent);
LPITEMIDLIST localPidl; //file pidl
parent->ParseDisplayName (0, 0, name, &eaten, &localPidl, 0);
parent->GetUIObjectOf (0, 0, (LPCITEMIDLIST *)&localPidl, IID_IContextMenu, 0, (void **)&cm); //gets context menu
messageLoop(); //window message loop
}
Any help is very appreciated.