how to copy text to the clipborad in c++? - c++

I am a new programmer in c++ and I can't understand how to use the clipboard to copy and paste like in any other program with text. Example please?
I am using Code::Blocks 16.01 MinGW32 g++ windows 10.

SetClipboardData should handle it.
glob = GlobalAlloc(GMEM_FIXED,32);
memcpy(glob,"it works",9);
OpenClipboard(hWnd);
EmptyClipboard();
SetClipboardData(CF_TEXT,glob);
CloseClipboard();
EDIT
This will get data out of clipboard and return that data in string.
std::string GetClipboardText()
{
OpenClipboard(nullptr);
HANDLE hData = GetClipboardData(CF_TEXT);
char * pszText = static_cast<char*>( GlobalLock(hData) );
std::string text( pszText );
GlobalUnlock( hData );
CloseClipboard();
return text;
}

For a cross-platform solution, you may use a library like ClipboardXX.
Usage example:
#include "clipboard.hpp"
#include <string>
int main()
{
clipboardxx::clipboard clipboard;
// copy
clipboard << "text you wanna copy";
// paste
std::string paste_text;
clipboard >> paste_text;
}
This may be preferrable for a Windows only software as well due to modern C++ being nicer to work with than the plain old Windows API.
Another useful library might be clip but I didn't test it myself.
Usage example:
#include "clip.h"
#include <iostream>
int main()
{
clip::set_text("Hello World");
std::string value;
clip::get_text(value);
std::cout << value << "\n";
}

Related

C++ how to find file path of the file I am working on in my program [duplicate]

I want to create a file in the current directory (where the executable is running).
My code:
LPTSTR NPath = NULL;
DWORD a = GetCurrentDirectory(MAX_PATH,NPath);
HANDLE hNewFile = CreateFile(NPath,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
I get exception at GetCurrentDirectory().
Why am I getting an exception?
I would recommend reading a book on C++ before you go any further, as it would be helpful to get a firmer footing. Accelerated C++ by Koenig and Moo is excellent.
To get the executable path use GetModuleFileName:
TCHAR buffer[MAX_PATH] = { 0 };
GetModuleFileName( NULL, buffer, MAX_PATH );
Here's a C++ function that gets the directory without the file name:
#include <windows.h>
#include <string>
#include <iostream>
std::wstring ExePath() {
TCHAR buffer[MAX_PATH] = { 0 };
GetModuleFileName( NULL, buffer, MAX_PATH );
std::wstring::size_type pos = std::wstring(buffer).find_last_of(L"\\/");
return std::wstring(buffer).substr(0, pos);
}
int main() {
std::cout << "my directory is " << ExePath() << "\n";
}
The question is not clear whether the current working directory is wanted or the path of the directory containing the executable.
Most answers seem to answer the latter.
But for the former, and for the second part of the question of creating the file, the C++17 standard now incorporates the filesystem library which simplifies this a lot:
#include <filesystem>
#include <iostream>
std::filesystem::path cwd = std::filesystem::current_path() / "filename.txt";
std::ofstream file(cwd.string());
file.close();
This fetches the current working directory, adds the filename to the path and creates an empty file. Note that the path object takes care of os dependent path handling, so cwd.string() returns an os dependent path string. Neato.
GetCurrentDirectory does not allocate space for the result, it's up to you to do that.
TCHAR NPath[MAX_PATH];
GetCurrentDirectory(MAX_PATH, NPath);
Also, take a look at Boost.Filesystem library if you want to do this the C++ way.
An easy way to do this is:
int main(int argc, char * argv[]){
std::cout << argv[0];
std::cin.get();
}
argv[] is pretty much an array containing arguments you ran the .exe with, but the first one is always a path to the executable. If I build this the console shows:
C:\Users\Ulisse\source\repos\altcmd\Debug\currentdir.exe
IMHO here are some improvements to anon's answer.
#include <windows.h>
#include <string>
#include <iostream>
std::string GetExeFileName()
{
char buffer[MAX_PATH];
GetModuleFileName( NULL, buffer, MAX_PATH );
return std::string(buffer);
}
std::string GetExePath()
{
std::string f = GetExeFileName();
return f.substr(0, f.find_last_of( "\\/" ));
}
#include <iostream>
#include <stdio.h>
#include <dirent.h>
std::string current_working_directory()
{
char* cwd = _getcwd( 0, 0 ) ; // **** microsoft specific ****
std::string working_directory(cwd) ;
std::free(cwd) ;
return working_directory ;
}
int main(){
std::cout << "i am now in " << current_working_directory() << endl;
}
I failed to use GetModuleFileName correctly. I found this work very well.
just tested on Windows, not yet try on Linux :)
WCHAR path[MAX_PATH] = {0};
GetModuleFileName(NULL, path, MAX_PATH);
PathRemoveFileSpec(path);
Please don't forget to initialize your buffers to something before utilizing them. And just as important, give your string buffers space for the ending null
TCHAR path[MAX_PATH+1] = L"";
DWORD len = GetCurrentDirectory(MAX_PATH, path);
Reference
You should provide a valid buffer placeholder.
that is:
TCHAR s[100];
DWORD a = GetCurrentDirectory(100, s);
#include <windows.h>
using namespace std;
// The directory path returned by native GetCurrentDirectory() no end backslash
string getCurrentDirectoryOnWindows()
{
const unsigned long maxDir = 260;
char currentDir[maxDir];
GetCurrentDirectory(maxDir, currentDir);
return string(currentDir);
}
You can remove the filename from GetModuleFileName() with more elegant way:
TCHAR fullPath[MAX_PATH];
TCHAR driveLetter[3];
TCHAR directory[MAX_PATH];
TCHAR FinalPath[MAX_PATH];
GetModuleFileName(NULL, fullPath, MAX_PATH);
_splitpath(fullPath, driveLetter, directory, NULL, NULL);
sprintf(FinalPath, "%s%s",driveLetter, directory);
Hope it helps!
GetCurrentDirectory() gets the current directory which is where the exe is invoked from. To get the location of the exe, use GetModuleFileName(NULL ...). if you have the handle to the exe, or you can derive it from GetCommandLine() if you don't.
As Mr. Butterworth points out, you don't need a handle.
Why does nobody here consider using this simple code?
TCHAR szDir[MAX_PATH] = { 0 };
GetModuleFileName(NULL, szDir, MAX_PATH);
szDir[std::string(szDir).find_last_of("\\/")] = 0;
or even simpler
TCHAR szDir[MAX_PATH] = { 0 };
TCHAR* szEnd = nullptr;
GetModuleFileName(NULL, szDir, MAX_PATH);
szEnd = _tcsrchr(szDir, '\\');
*szEnd = 0;
I guess, that the easiest way to locate the current directory is to cut it from command line args.
#include <string>
#include <iostream>
int main(int argc, char* argv[])
{
std::string cur_dir(argv[0]);
int pos = cur_dir.find_last_of("/\\");
std::cout << "path: " << cur_dir.substr(0, pos) << std::endl;
std::cout << "file: " << cur_dir.substr(pos+1) << std::endl;
return 0;
}
You may know that every program gets its executable name as first command line argument. So you can use this.
Code snippets from my CAE project with unicode development environment:
/// #brief Gets current module file path.
std::string getModuleFilePath() {
TCHAR buffer[MAX_PATH];
GetModuleFileName( NULL, buffer, MAX_PATH );
CT2CA pszPath(buffer);
std::string path(pszPath);
std::string::size_type pos = path.find_last_of("\\/");
return path.substr( 0, pos);
}
Just use the templete CA2CAEX or CA2AEX which calls the internal API ::MultiByteToWideChar or ::WideCharToMultiByte。
if you don't want to use std, you can use this code:
char * ExePath()
{
static char buffer[MAX_PATH] = { 0 };
GetModuleFileName( NULL, buffer, MAX_PATH );
char * LastSlash = strrchr(buffer, '\\');
if(LastSlash == NULL)
LastSlash = strrchr(buffer, '/');
buffer[LastSlash-buffer] = 0;
return buffer;
}
I simply use getcwd() method for that purpose in Windows, and it works pretty well. The code portion is like following:
char cwd[256];
getcwd(cwd, 256);
string cwd_str = string(cwd);
The <unistd.h> library has to be added though.
To find the directory where your executable is, you can use:
TCHAR szFilePath[_MAX_PATH];
::GetModuleFileName(NULL, szFilePath, _MAX_PATH);
If you are using the Poco library, it's a one liner and it should work on all platforms I think.
Poco::Path::current()
On a give Windows C++ IDE I went crude and it was simple, reliable, but slow:
system( "cd" );
String^ exePath = Application::ExecutablePath;<br>
MessageBox::Show(exePath);
In Windows console, you can use the system command CD (Current Directory):
std::cout << "Current Directory = ";
system("cd"); // to see the current executable directory

When to use _Notnull_ in C++?

Can someone provide insight when to use _Notnull_? I'm using Visual Studio 2019 and here is my code:
#include <windows.h>
#include <vector>
void WriteIt(_Notnull_ CONST WCHAR* sMsg, _Notnull_ CONST WCHAR* sFileName)
{
FILE* stream;
errno_t err = _wfopen_s(&stream, sFileName, L"a+");
if (err == 0)
if (stream)
{
fwprintf_s(stream, L"%s", sMsg);
fclose(stream);
}
}
int main()
{
WCHAR *sMessage = new WCHAR[16]();
WCHAR *sFile = NULL;
sFile = NULL;
WriteIt(sMessage, sFile);
}
Yet, the _Notnull_ lets the function run. I can't find any documentation on how/why to use it with examples.
Thanks #François Andrieux. Looks like it is used when doing a code analysis from within Visual Studio, where the analyzer can pinpoint if an incoming pointer could be NULL. Here is what the code analyzer says with _Notnull_ is included: Warning C6387 'sFile' could be '0': this does not adhere to the specification for the function 'WriteIt'. Very helpful!

Why does GetPointCount of a GraphicsPath always return 0?

I am trying to learn the gdiplus windows API, and in particular how to use GraphicsPath to get points from different shapes. I noticed that I could never get anything to appear from microsoft's example code, so I tried to see how many points were actually in a GraphicsPath like this:
#include <windows.h>
#include <gdiplus.h>
#include <iostream>
//use gdiplus library when compiling
#pragma comment( lib, "gdiplus" )
using namespace Gdiplus;
VOID GetPointCountExample()
{
// Create a path that has one ellipse and one line.
GraphicsPath path;
path.AddLine(220, 120, 300, 160);
// Find out how many data points are stored in the path.
int count = path.GetPointCount();
std::cout << count << std::endl;
}
int main()
{
GetPointCountExample();
}
This always returned a count of 0. Why is this?
I have tried compiling with mingw-64 and Visual Studio with the same result.
I also tried printing out the Gdiplus::Status returned from this:
GraphicsPath path;
int stat = path.StartFigure();
std::cout << stat << std::endl;
Which printed a status of 2, "InvalidParameter" even though StartFigure doesn't take parameters.
Ahh read more documentation and found this: The GdiplusStartup function initializes Windows GDI+. Call GdiplusStartup before making any other GDI+ calls
https://learn.microsoft.com/en-us/windows/win32/api/Gdiplusinit/nf-gdiplusinit-gdiplusstartup
This code works:
#include <windows.h>
#include <gdiplus.h>
#include <iostream>
//use gdiplus library when compiling
#pragma comment( lib, "gdiplus" )
using namespace Gdiplus;
VOID GetPointCountExample()
{
// Create a path that has one ellipse and one line.
GraphicsPath path;
path.AddLine(0, 0, 0, 1);
// Find out how many data points are stored in the path.
int count = path.GetPointCount();
std::cout << count << std::endl;
}
int main()
{
//Must call GdiplusStartup before making any GDI+ calls
//https://learn.microsoft.com/en-us/windows/win32/api/Gdiplusinit/nf-gdiplusinit-gdiplusstartup
ULONG_PTR token;
GdiplusStartupInput input;
input.GdiplusVersion = 1;
input.SuppressBackgroundThread = false;
GdiplusStartup(&token, &input, NULL);
GetPointCountExample();
//Shutdown GDI+ when finished using
GdiplusShutdown(token);
}

C++ Why does my code put a registry key at the wrong directory?

So, I want to put a registry key at the directory HKCU\Software\Microsoft\Windows\CurrentVersion\Run, and I want it to be called Test, and have it contain "TestText", but instead this code puts a new key at HKCU\Test and the program writes random Chinese characters in the registry key. Anyone help?
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <string>
#include <time.h>
using namespace std;
int main()
{
HKEY keyExample;
if (RegOpenKey(HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Run\\"), &keyExample) != ERROR_SUCCESS)
{
RegCloseKey(keyExample);
return 69;
}
if (RegSetKeyValue(HKEY_CURRENT_USER, TEXT("Test"), 0, REG_SZ, (LPBYTE)"TestText", strlen("TestText")*sizeof(char)) != ERROR_SUCCESS)
{
RegCloseKey(keyExample);
cout << "Unable to set registry value value_name";
}
RegCloseKey(keyExample);
return 0;
}
RegSetKeyValue(HKEY_CURRENT_USER, ...
This is the bug. You need to use the keyExample you got when you opened the key you wanted. Like this:
RegSetKeyValue(keyExample, ...
And for your ANSI/Unicode problem, you need to use the TEXT() macro for your actual data, not just its name:
RegSetKeyValue(keyExample, TEXT("Test"), 0, REG_SZ, TEXT("TestText"), lstrlen(TEXT("TestText"))*sizeof(TCHAR))
It's generally easier to forget all the legacy backward compatible stuff related to the TEXT/TCHAR menus and to directly call the W versions of the Windows API functions with long strings.

On Windows is there an interface for Copying Folders?

I want to copy folder A and paste to desktop.
I am currently using C++ so preferably an OO interface if available.
On Windows (Win32), you could use SHFileOperation, eg:
SHFILEOPSTRUCT s = { 0 };
s.hwnd = m_hWnd;
s.wFunc = FO_COPY;
s.fFlags = FOF_SILENT;
s.pTo = "C:\\target folder\0";
s.pFrom = "C:\\source folder\\*\0";
SHFileOperation(&s);
Use this
bool CopyDirTo( const wstring& source_folder, const wstring& target_folder )
{
wstring new_sf = source_folder + L"\\*";
WCHAR sf[MAX_PATH+1];
WCHAR tf[MAX_PATH+1];
wcscpy_s(sf, MAX_PATH, new_sf.c_str());
wcscpy_s(tf, MAX_PATH, target_folder.c_str());
sf[lstrlenW(sf)+1] = 0;
tf[lstrlenW(tf)+1] = 0;
SHFILEOPSTRUCTW s = { 0 };
s.wFunc = FO_COPY;
s.pTo = tf;
s.pFrom = sf;
s.fFlags = FOF_SILENT | FOF_NOCONFIRMMKDIR | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NO_UI;
int res = SHFileOperationW( &s );
return res == 0;
}
Starting with Visual Studio 2015 you can use std::filesystem::copy which is even platform independent since it is available in implementations supporting >= C++17.
#include <exception>
#include <experimental/filesystem> // C++-standard filesystem header file in VS15, VS17.
#include <iostream>
namespace fs = std::experimental::filesystem; // experimental for VS15, VS17.
/*! Copies all contents of path/to/source/directory to path/to/target/directory.
*/
int main()
{
fs::path source = "path/to/source/directory";
fs::path targetParent = "path/to/target";
auto target = targetParent / source.filename(); // source.filename() returns "directory".
try // If you want to avoid exception handling then use the error code overload of the following functions.
{
fs::create_directories(target); // Recursively create target directory if not existing.
fs::copy(source, target, fs::copy_options::recursive);
}
catch (std::exception& e) // Not using fs::filesystem_error since std::bad_alloc can throw too.
{
std::cout << e.what();
}
}
Change the behaviour of fs::copy with std::filesystem::copy_options. I've used std::filesystem::path::filename to retrieve the source directory name without having to type it manually.
(assuming Windows)
Use can use ShFileOperation (or IFileOperation::CopyItem on Vista).
Max.
For a platform agnostic solution, I'd suggest Boost::filesystem. That link is basically the reference material. There is a copy_file method that copies a file from one location to another.
On Windows, the desktop is a special folder:
// String buffer for holding the path.
TCHAR strPath[ MAX_PATH ];
// Get the special folder path.
SHGetSpecialFolderPath(
0, // Hwnd
strPath, // String buffer.
CSIDL_DESKTOPDIRECTORY, // CSLID of folder
FALSE ); // Create if doesn't exists?
Here's an example using SHFileOperation:
http://msdn.microsoft.com/en-us/library/bb776887%28VS.85%29.aspx#example
Here's a quick hack without it:
#import <stdlib.h>
int main(int argc, char *argv[]) {
system("robocopy \"C:\\my\\folder\" \"%userprofile%\\desktop\\\" /MIR");
return 0;
}
it works
#include <iostream>
int main()
{
system("xcopy C:\\Users\\Elmi\\Desktop\\AAAAAA\ C:\\Users\\Elmi\\Desktop\\b\ /e /i /h");
return 0;
}