Author Topic: "prefill" the buffer  (Read 2246 times)

Magnum

  • Member
  • *****
  • Posts: 2235
"prefill" the buffer
« on: December 04, 2013, 02:56:18 AM »
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.?

Code: [Select]
; 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
Take care,
                   Andy

Ubuntu-mate-16.04-desktop-amd64

http://www.goodnewsnetwork.org

dedndave

  • Member
  • *****
  • Posts: 8734
  • Still using Abacus 2.0
    • DednDave
Re: "prefill" the buffer
« Reply #1 on: December 04, 2013, 04:29:37 AM »
i don't recall if this is tested or not, Andy
but, it looks right   :P
Code: [Select]
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

Vortex

  • Member
  • *****
  • Posts: 1704
Re: "prefill" the buffer
« Reply #2 on: December 04, 2013, 06:06:39 AM »
masm32.lib provides the function SetClipboardText

dedndave

  • Member
  • *****
  • Posts: 8734
  • Still using Abacus 2.0
    • DednDave
Re: "prefill" the buffer
« Reply #3 on: December 04, 2013, 06:11:24 AM »
yah - i opted to write my own because that one doesn't handle errors
Code: [Select]
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

Magnum

  • Member
  • *****
  • Posts: 2235
Re: "prefill" the buffer
« Reply #4 on: December 04, 2013, 07:04:54 AM »
hWnd    = handle of owner window

I am pretty rusty with this.

Take care,
                   Andy

Ubuntu-mate-16.04-desktop-amd64

http://www.goodnewsnetwork.org

dedndave

  • Member
  • *****
  • Posts: 8734
  • Still using Abacus 2.0
    • DednDave
Re: "prefill" the buffer
« Reply #5 on: December 04, 2013, 07:44:08 AM »
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

dedndave

  • Member
  • *****
  • Posts: 8734
  • Still using Abacus 2.0
    • DednDave
Re: "prefill" the buffer
« Reply #6 on: December 04, 2013, 08:30:39 AM »
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