I had more examples of putting text on the clipboard but lost them because a made a mistake in my backup batch file. :(
On the bright side, I only lost 6 months of code.
I would like to find out if it's possible to "prefill" the buffer with each computer startup.
Would running this as a Startup Item be the most efficient method.?
; Txt_From_HK.asm Beta version
;
; Creates CTRL ALT A keyboard combination shortcut.
; Ctrl Alt A to activate, then Shift Insert to insert text
; 2010 QHR Inc.
include \masm32\include\masm32rt.inc
WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
.data
hglb dd 0 ; ',\ ; need space before quote
str1 db 'Ich habe keine Ahnung.', 0
str2 db 'user2', 0
ClassName db "DLGCLASS",0
DlgName db "MyDialog",0
AppName db "Ctrl_Alt_A",0
Mess1 db "SetClipboardData failed",0
Mess2 db "GlobalAlloc failed",0
Mess3 db "OpenClipboard failed",0
.data?
hInstance HINSTANCE ?
CommandLine LPSTR ?
.code
start:
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke GetCommandLine
mov CommandLine,eax
invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
invoke ExitProcess,eax
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL hWnd:HWND
mov wc.cbSize,SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,NULL
push hInst
pop wc.hInstance
mov wc.hbrBackground,COLOR_WINDOW+1
mov wc.lpszMenuName,NULL
mov wc.lpszClassName,OFFSET ClassName
invoke LoadIcon,NULL,IDI_APPLICATION
mov wc.hIcon,eax
mov wc.hIconSm,0
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
invoke RegisterClassEx, addr wc
INVOKE CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\
hInst,NULL
mov hWnd,eax
invoke ShowWindow, hWnd,SW_MINIMIZE ;Minimal window
invoke UpdateWindow, hWnd
.WHILE TRUE
INVOKE GetMessage, ADDR msg,NULL,0,0
.BREAK .IF (!eax)
invoke IsDialogMessage, hWnd, ADDR msg
.if eax==FALSE
INVOKE TranslateMessage, ADDR msg
INVOKE DispatchMessage, ADDR msg
.endif
.ENDW
mov eax,msg.wParam
ret
WinMain endp
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.if uMsg==WM_CREATE
invoke RegisterHotKey,hWnd,065h,MOD_CONTROL or MOD_ALT, 041h ; CTRL ALT A
invoke RegisterHotKey,hWnd,066h,MOD_CONTROL or MOD_ALT, 042h ; CTRL ALT B
.ELSEIF uMsg==WM_DESTROY
invoke UnregisterHotKey,hWnd,065h
invoke GlobalFree,hglb ; help by Nathan in comp.lang.asm.x86
invoke PostQuitMessage,NULL
.ELSEIF uMsg == WM_HOTKEY
; OpenClipboard
; SetClipboardData
; CloseClipboard
; Put text on the clipboard.
invoke OpenClipboard,NULL
.IF (eax)
invoke EmptyClipboard
invoke GlobalAlloc,GMEM_MOVEABLE, 128 ;; Allocate some space.
.IF (eax)
mov hglb, eax
invoke GlobalLock,hglb
mov ebx, eax
push ebx ;; Save ebx
mov eax, lParam
shr eax, 16
.if ax == 65 ;; If the key 65 ("A") was pressed.
invoke MemCopy,ADDR str1,ebx,SIZEOF str1
.elseif ax == 66 ;; If the key 66 ("B") was pressed.
invoke MemCopy,ADDR str2,ebx,SIZEOF str2
.else
;; Some other key pressed.
.endif
invoke SetClipboardData,CF_TEXT,hglb
.IF (eax == 0)
invoke MessageBox,NULL, ADDR AppName,ADDR Mess1, MB_ICONEXCLAMATION
.ENDIF
pop eax ;; Restore the value that was saved from ebx
invoke GlobalUnlock, eax
.ELSE
invoke MessageBox,NULL, ADDR AppName,ADDR Mess2, MB_ICONEXCLAMATION
.ENDIF
invoke GlobalFree, hglb
invoke CloseClipboard
.ELSE
invoke MessageBox,NULL, ADDR AppName,ADDR Mess3, MB_ICONEXCLAMATION
.ENDIF
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF
xor eax,eax
ret
WndProc endp
end start
i don't recall if this is tested or not, Andy
but, it looks right :P
ClipCopy PROC USES EBX hWnd:HWND,nLength:UINT,lpText:LPVOID
;Copy Text to Clipboard, David R. Sheldon, DednDave, 3-2011
;-----------------------------------
;Call With: hWnd = handle of owner window
; nLength = length of string
; lpText = pointer to string
;
; Returns: EAX = non-zero if successful
;
;Also Uses: ECX, EDX destroyed
; EBX, EBP, ESI, EDI preserved
;-----------------------------------
LOCAL dwStatus :DWORD
;-----------------------------------
INVOKE OpenClipboard,hWnd
.if eax
mov ecx,nLength
add ecx,32
and cl,-32
INVOKE GlobalAlloc,GMEM_MOVEABLE or GMEM_DDESHARE,ecx
mov dwStatus,eax
.if eax
xchg eax,ebx
INVOKE EmptyClipboard
mov dwStatus,eax
.if eax
push esi
INVOKE GlobalLock,ebx
mov esi,lpText
mov ecx,nLength
xchg eax,edi
rep movsb
mov byte ptr [edi],0
xchg eax,edi
INVOKE GlobalUnlock,ebx
INVOKE SetClipboardData,CF_OEMTEXT,ebx
pop esi
mov dwStatus,eax
.endif
INVOKE GlobalFree,ebx
.endif
INVOKE CloseClipboard
mov eax,dwStatus
.endif
ret
ClipCopy ENDP
masm32.lib provides the function SetClipboardText
yah - i opted to write my own because that one doesn't handle errors
SetClipboardText proc ptxt:DWORD
LOCAL hMem :DWORD
LOCAL pMem :DWORD
LOCAL slen :DWORD
invoke StrLen, ptxt ; get length of text
mov slen, eax
add slen, 64
invoke GlobalAlloc,GMEM_MOVEABLE or \
GMEM_DDESHARE,slen ; allocate memory
mov hMem, eax
invoke GlobalLock,hMem ; lock memory
mov pMem, eax
cst pMem, ptxt ; copy text to allocated memory
invoke OpenClipboard,NULL ; open clipboard
invoke SetClipboardData,CF_TEXT,pMem ; write data to it
invoke CloseClipboard ; close clipboard
invoke GlobalUnlock,hMem ; unlock memory
invoke GlobalFree,hMem ; deallocate memory
ret
SetClipboardText endp
hWnd = handle of owner window
I am pretty rusty with this.
in a normal GUI app, you can assign the owner window to be your top-level window
if you don't care, you can use NULL (= HWND_DESKTOP)
of course, if other apps do the same thing - well - no telling if you have exclusive access or not - lol
typically, you open the clipboard, write stuff, and close it all in a matter of microseconds
also - if you're writing a console app, you can use GetConsoleWindow
notice that, if you attempt to open the clipboard when some other window has it open, it will fail
that's why i thought it was important to handle error conditions properly
also - i did things in a little different order
i combined a number of sources of information to arrive at that order
mainly, MSDN's example code - but i think even that had some problems
you may have to read the user comments on the MSDN function pages