* Windows clipboard example; * Richard A. DeVenezia; * http://www.devenezia.com; filename sascbtbl catalog 'work.windows.api.source'; data _null_; file sascbtbl; input; put _infile_; cards4; routine FindWindowA module=USER32 minarg=2 maxarg=2 stackpop=called returns=long ; arg 1 num input byvalue notreqd format=pib4.; arg 2 char input byaddr notreqd format=$cstr200.; routine RegisterClipboardFormatA module=USER32 minarg=1 maxarg=1 stackpop=called returns=long ; arg 1 char input byaddr format=$cstr200.; routine OpenClipboard module=USER32 minarg=1 maxarg=1 stackpop=called returns=long ; arg 1 input num byvalue format=pib4.; * hwnd; * returns non-zero if successful; routine EmptyClipboard module=USER32 minarg=0 maxarg=0 stackpop=called returns=long ; * returns non-zero if successful; routine CloseClipboard module=USER32 minarg=0 maxarg=0 stackpop=called returns=long ; * returns non-zero if successful; routine SetClipboardData module=USER32 minarg=2 maxarg=2 stackpop=called returns=long ; arg 1 input num byvalue format=pib4.; * UINT uFormat; arg 2 input num byvalue format=pib4.; * HANDLE hMem (use addr()); * returns hMem if successful; routine GlobalAlloc module=KERNEL32 minarg=2 maxarg=2 stackpop=called returns=long ; arg 1 num input byvalue format=pib4.; * UINT uFlags, // object allocation attributes ; arg 2 num input byvalue format=pib4.; * DWORD dwBytes // number of bytes to allocate ; routine GlobalLock module=KERNEL32 minarg=1 maxarg=1 stackpop=called returns=long ; arg 1 num input byvalue format=pib4.; * HGLOBAL hMem // address of the global memory object; routine GlobalUnlock module=KERNEL32 minarg=1 maxarg=1 stackpop=called returns=long ; arg 1 num input byvalue format=pib4.; * HGLOBAL hMem // address of the global memory object; routine RtlMoveMemory module=KERNEL32 minarg=3 maxarg=3 stackpop=called ; arg 1 num input byvalue format=pib4.; * destination address; arg 2 num input byvalue format=pib4.; * source, use addr(); arg 3 num input byvalue format=pib4.; * number of bytes to copy; ;;;; run; %macro SetClipboardText ( string ); %local CF_TEXT; %let CF_TEXT = 1; cf_text = &CF_TEXT; hwnd = modulen ('FindWindowA',0,'SAS'); rc = modulen ('OpenClipboard', hwnd); rc = modulen ('EmptyClipboard'); length clipdata $32767; clipdata = trim(&string) || '00'x; %SetClipboardData ( cf_text, clipdata ); %mend; %macro SetClipboardHTML ( string ); %local CF_HTML; %let CF_HTML = 'HTML Format'; cf_html = modulen ('RegisterClipboardFormatA', &CF_HTML); hwnd = modulen ('FindWindowA',0,'SAS'); rc = modulen ('OpenClipboard', hwnd); rc = modulen ('EmptyClipboard'); ofl = 10; of = 'z' || trim(left(put(ofl,4.))) || '.'; * offset position value format; length clipdata $32767; clipdata = 'Version:1.0' ||crlf||'StartHTML:' || putn (0,of) ||crlf||'EndHTML:' || putn (0,of) ||crlf||'StartFragment:' || putn (0,of) ||crlf||'EndFragment:' || putn (0,of) ||crlf||'' ||crlf||'' ||crlf ||&string ||crlf||'' ||crlf||'' ||'00'x ; length tag $20; tag = 'StartHTML:'; p1 = index (clipdata, trim(tag)) + length (tag); p2 = index (clipdata, '') - 1; substr (clipdata, p1, ofl) = putn (p2, of); tag = 'EndHTML:'; p1 = index (clipdata, trim(tag)) + length (tag); p2 = length (clipdata) - 1; substr (clipdata, p1, ofl) = putn (p2, of); tag = 'StartFragment:'; p1 = index (clipdata, trim(tag)) + length (tag); p2 = index (clipdata, '