string - Saving struct to clipboard in C++ -
i have structure in c++ code:
struct sdata { dword number; int currentnumber; bool gameover; };
i need save clipboard structure 1 process. , other process need load again structure. can easy cstrings/strings not structures. suggest me?
this method setting cstring clipboard:
bool settext(cstring text) { cstring source; source = text; //put text in source if (openclipboard(null)) { hglobal clipbuffer; char * buffer; emptyclipboard(); clipbuffer = globalalloc(gmem_ddeshare, source.getlength() + 1); buffer = (char*)globallock(clipbuffer); strcpy(buffer, lpcstr(source)); globalunlock(clipbuffer); setclipboarddata(cf_text, clipbuffer); closeclipboard(); return true; } else { return false; } }
and getter:
std::string gettext(void) const { return (const char*)getclipboarddata(cf_text); }
you need register own clipboard format, can store struct
data as-is.
static uint cf_mystructdata = registerclipboardformat(text("mystructdata")); #pragma pack(push, 1) struct sdata { dword number; int currentnumber; bool gameover; }; #pragma pack(pop) bool setdata(const sdata &data) { if (cf_mystructdata == 0) return false; bool bok = false; if (openclipboard(null)) { if (emptyclipboard()) { hglobal clipbuffer = globalalloc(gmem_moveable, sizeof(sdata)); if (clipbuffer) { sdata *buffer = (sdata*) globallock(clipbuffer); if (buffer) { *buffer = data; globalunlock(clipbuffer); bok = setclipboarddata(cf_mystructdata, clipbuffer); } if (!bok) globalfree(clipbuffer); } } closeclipboard(); } return bok; } bool getdata(sdata &data) const { if (cf_mystructdata == 0) return false; bool bok = false; if (openclipboard(null)) { handle clipbuffer = getclipboarddata(cf_mystructdata); if (clipbuffer) { sdata *buffer = (sdata*) globallock(clipbuffer); if (buffer) { data = *buffer; globalunlock(clipbuffer); bok = true; } } closeclipboard(); } return bok; }
alternatively, using c++ raii wrappers:
struct clipboard { clipboard(hwnd hwnd = null) { if (!openclipboard(hwnd)) throw std::runtime_error("error opening clipboard"); } ~clipboard() { closeclipboard(); } void empty() { if (!emptyclipboard()) throw std::runtime_error("error emptying clipboard"); } template<typename t> struct databuffer { hglobal _hmem; bool _free; struct lock { databuffer& _buffer; t* _data; lock(databuffer &buffer) : _buffer(buffer), _locked(false) { _data = (t*) globallock(_buffer.get()); if (!_data) throw std::runtime_error("error locking memory"); } ~lock() { globalunlock(_buffer.get()); } t& data() { return *_data; } }; databuffer(const t &data) : _hmem(null), _free(true) { _hmem = globalalloc(gmem_moveable, sizeof(t)); if (!_hmem) throw std::runtime_error("error allocating memory"); lock(*this).data() = data; } databuffer(hglobal hmem) : _hmem(mem), _free(false) { if (globalsize(_hmem)) < sizeof(t)) throw std::runtime_error("bad memory size"); } ~databuffer() { if ((_hmem) && (_free)) globalfree(_hmem); } hglobal release() { hglobal tmp = _hmem; _hmem = null; return tmp; } hglobal get() { return _hmem; } void copy(t &data) { data = lock(*this).data(); } }; template<typename t> void setdata(uint format, const t &data) { databuffer<t> buffer(data); if (!setclipboarddata(format, buffer.get())) throw std::runtime_error("error setting clipboard data"); buffer.release(); } template<typename t> void getdata(uint format, t &data) { databuffer<t> buffer(getclipboarddata(format)); if (!buffer.get()) throw std::runtime_error("error getting clipboard data"); buffer.copy(data); } };
bool setdata(const sdata &data) { if (cf_mystructdata != 0) { try { clipboard clipbrd; clipbrd.empty(); clipbrd.setdata(cf_mystructdata, data); return true; } catch (const std::runtime_error&) { } } return false; } bool getdata(sdata &data) const { if (cf_mystructdata != 0) { try { clipboard clipbrd; clipbrd.getdata(cf_mystructdata, data); return true; } catch (const std::runtime_error&) { } } return false; }
Comments
Post a Comment