|
Post by Fabio Siciliano on Jun 7, 2020 15:17:02 GMT -5
Hello everybody, I'm struggling very hard with the SendInput API function ( #user32) which in my code (see below) is always ending with error code 87 ( 0x00000057 = ERROR_INVALID_PARAMETER = "The parameter is incorrect" as you can find here: Win32 Error Codes). I have tried various configurations about the INPUT struct (pInputs, iUnion, mInput, kInput, hInput) but unsuccessfully so far. Any suggestion? I'm trying to send the MAINWIN a sequence of CTRL+A, CTRL+C to get the whole edit control text into the Windows clipboard... mainwin 120 30 : titlebar "getMainwinTEXT (experimental)"
'** FormatMessageA (kernel32) struct lpSource, lpSource as long struct Arguments, Arguments as long
global nu$, cr$, nl2$, caption$ nul$ = chr$(0) : lf$ = chr$(10) : cr$ = chr$(13) : nl$ = cr$; lf$ : nl2$ = nl$; nl$
myApp$ = "getMainwinTEXT" : caption$ = myApp$; cr$
print "Welcome to my getMainwinTEXT experiment!" print "Hope you will enjoy it..." print "Let's see if it work." print
global INPUT.KEYBOARD, KEYEVENTF.KEYUP, VK.A, VK.C INPUT.KEYBOARD = 1 : KEYEVENTF.KEYUP = hexdec("2") : VK.A = hexdec("41") : VK.C = hexdec("43")
struct mInput, dx as long, dy as long, mouseData as ulong, dwFlags as ulong, time as ulong, dwExtraInfo as ulong struct kInput, wVk as word, wScan as word, dwFlags as ulong, time as ulong, dwExtraInfo as ulong struct hInput, uMsg as ulong, wParamL as word, wParamH as word
struct iUnion, mInput as struct, kInput as struct, hInput as struct
struct pInputs, type as ulong, iUnion as struct
r = SendInput(_VK_CONTROL, "down") r = SendInput(VK.A, "down") r = SendInput(VK.A, "up") r = SendInput(_VK_CONTROL, "up")
r = SendInput(_VK_CONTROL, "down") r = SendInput(VK.C, "down") r = SendInput(VK.C, "up") r = SendInput(_VK_CONTROL, "up")
[send2keys]
function SendInput(wVk, mode$)
cInputs = 1 kInput.wVk.struct = wVk
if mode$ = "up" then kInput.dwFlags.struct = KEYEVENTF.KEYUP else kInput.dwFlags.struct = 0
pInputs.type.struct = INPUT.KEYBOARD
iUnion.mInput.struct = mInput.struct iUnion.kInput.struct = kInput.struct iUnion.hInput.struct = hInput.struct
pInputs.iUnion.struct = iUnion.struct
cbSize = len(iUnion.struct)
calldll #user32, "SendInput", _ cInputs as ulong, _ pInputs as struct, _ cbSize as long, _ SendInput as ulong
if SendInput = 0 then calldll #kernel32, "GetLastError", r as long r$ = "SendInput (#user32) = "; str$(r) notice caption$; formatMessage$(r$, r) end if
end function
[formatMessage]
function formatMessage$(source$, rc)
dwFlags = _FORMAT_MESSAGE_FROM_SYSTEM or _FORMAT_MESSAGE_ALLOCATE_BUFFER dwMessageId = rc
calldll #kernel32, "FormatMessageA", _ dwFlags as long, _ lpSource as struct, _ dwMessageId as long, _ dwLanguageId as long, _ lpBuffer$ as ptr, _ nSize as long, _ Arguments as struct, _ r as long
dwFlags = _FORMAT_MESSAGE_FROM_SYSTEM nSize = r + 1 lpBuffer$ = space$(nSize) + nul$
calldll #kernel32, "FormatMessageA", _ dwFlags as long, _ lpSource as struct, _ dwMessageId as long, _ dwLanguageId as long, _ lpBuffer$ as ptr, _ nSize as long, _ Arguments as struct, _ r as long
if r then formatMessage$ = source$; nl2$; trim$(lpBuffer$) else formatMessage$ = translate$("No further info is available"); "." end if
lpBuffer$ = ""
end function
[translate]
function translate$(text$) translate$ = text$ end function
Thank you all in advance. Fabio
|
|
|
Post by Chris Iverson on Jun 7, 2020 15:36:59 GMT -5
Couple things I notice right away:
The INPUT structure is not a combination of the three different types of inputs. It's a union. The three structs are overlaid on each other, so you only need to set up the keyboard input structure.
Additionally, the way you're referencing the structs right now, you're creating the union structure as pointers to the other structs, which isn't going to work. They're embedded, not pointers.
Give me a little while to play with this.
EDIT: Yup, got it working. Had to make a couple extra changes, too.
One, needed to include the keyboard scan code, not just the VK code. Both are needed to simulate keyboard input. I got the codes from here: https://gist.github.com/tracend/912308
Two, needed to extend the keyboard input struct, since the INPUT struct is a union with two other structs, including a longer/larger struct, it needed to be made larger to fit the size check.
mainwin 120 30 : titlebar "getMainwinTEXT (experimental)"
'** FormatMessageA (kernel32) struct lpSource, lpSource as long struct Arguments, Arguments as long
global nu$, cr$, nl2$, caption$ nul$ = chr$(0) : lf$ = chr$(10) : cr$ = chr$(13) : nl$ = cr$; lf$ : nl2$ = nl$; nl$
myApp$ = "getMainwinTEXT" : caption$ = myApp$; cr$
print "Welcome to my getMainwinTEXT experiment!" print "Hope you will enjoy it..." print "Let's see if it work." print
global INPUT.KEYBOARD, KEYEVENTF.KEYUP, VK.A, VK.C INPUT.KEYBOARD = 1 : KEYEVENTF.KEYUP = hexdec("2") : VK.A = hexdec("41") : VK.C = hexdec("43")
scanCodeCtrl = hexdec("1D") scanCodeA = hexdec("1E") scanCodeC = hexdec("2E")
'struct mInput, dx as long, dy as long, mouseData as ulong, dwFlags as ulong, time as ulong, dwExtraInfo as ulong 'struct kInput, wVk as word, wScan as word, dwFlags as ulong, time as ulong, dwExtraInfo as ulong 'struct hInput, uMsg as ulong, wParamL as word, wParamH as word
'struct iUnion, mInput as struct, kInput as struct, hInput as struct
'The dummy parameters are needed to fill up space that would otherwise be taken up by the other structs struct pInputs, type as ulong, wVk as word, wScan as word, dwFlags as ulong, time as ulong, dwExtraInfo as ulong,_ dummy1 as long, dummy2 as long
r = SendInput(_VK_CONTROL, "down", scanCodeCtrl) r = SendInput(VK.A, "down", scanCodeA) r = SendInput(VK.A, "up", scanCodeA) r = SendInput(_VK_CONTROL, "up", scanCodeCtrl)
r = SendInput(_VK_CONTROL, "down", scanCodeCtrl) r = SendInput(VK.C, "down", scanCodeC) r = SendInput(VK.C, "up", scanCodeC) r = SendInput(_VK_CONTROL, "up", scanCodeCtrl)
[send2keys]
function SendInput(wVk, mode$, scanCode)
cInputs = 1 'kInput.wVk.struct = wVk pInputs.wVk.struct = wVk pInputs.wScan.struct = scanCode
'if mode$ = "up" then kInput.dwFlags.struct = KEYEVENTF.KEYUP else kInput.dwFlags.struct = 0 if mode$ = "up" then pInputs.dwFlags.struct = KEYEVENTF.KEYUP else pInputs.dwFlags.struct = 0
pInputs.type.struct = INPUT.KEYBOARD
'iUnion.mInput.struct = mInput.struct 'iUnion.kInput.struct = kInput.struct 'iUnion.hInput.struct = hInput.struct
'pInputs.iUnion.struct = iUnion.struct
cbSize = len(pInputs.struct)
calldll #user32, "SendInput", _ cInputs as ulong, _ pInputs as struct, _ cbSize as long, _ SendInput as ulong
if SendInput = 0 then calldll #kernel32, "GetLastError", r as long r$ = "SendInput (#user32) = "; str$(r) notice caption$; formatMessage$(r$, r) end if
end function
[formatMessage]
function formatMessage$(source$, rc)
dwFlags = _FORMAT_MESSAGE_FROM_SYSTEM or _FORMAT_MESSAGE_ALLOCATE_BUFFER dwMessageId = rc
calldll #kernel32, "FormatMessageA", _ dwFlags as long, _ lpSource as struct, _ dwMessageId as long, _ dwLanguageId as long, _ lpBuffer$ as ptr, _ nSize as long, _ Arguments as struct, _ r as long
dwFlags = _FORMAT_MESSAGE_FROM_SYSTEM nSize = r + 1 lpBuffer$ = space$(nSize) + nul$
calldll #kernel32, "FormatMessageA", _ dwFlags as long, _ lpSource as struct, _ dwMessageId as long, _ dwLanguageId as long, _ lpBuffer$ as ptr, _ nSize as long, _ Arguments as struct, _ r as long
if r then formatMessage$ = source$; nl2$; trim$(lpBuffer$) else formatMessage$ = translate$("No further info is available"); "." end if
lpBuffer$ = ""
end function
[translate]
function translate$(text$) translate$ = text$ end function
|
|
|
Post by Fabio Siciliano on Jun 8, 2020 3:36:50 GMT -5
Wonderful Chris... really a great job, thank you!
Fabio
|
|
|
Post by Fabio Siciliano on Jun 9, 2020 8:37:00 GMT -5
Hi Chris, just an update...
I've just discovered that scan codes are mandatory for alphanumeric chars only: for controls (such as CTRL, HOME, END and so on), instead, simply passing zero is allowed.
Have a nice day!
Fabio
|
|
|
Post by Fabio Siciliano on Jun 9, 2020 9:27:29 GMT -5
Here you can find my full demonstration program with credits...
'** TEST program to show how to copy text from the MAINWIN into the Windows Clipboard (and retrieving it!) '** by Fabio Siciliano, June, 7th, 2020 (last update: June, 9th, 2020)
'** CREDITS: thanks to Chris Iverson (Administrator of Liberty BASIC Community Forum) who figured out how to deal with the INPUT struct and scan codes '** on June, 7th, 2020 (https://libertybasiccom.proboards.com/thread/1118/struggling-sendinput-api-function-user32?page=1&scrollTo=7815) ' '** Thanks also to Alice Watson for her very useful article "CLIPBOARD API DEMOS" (http://libertybasicuniversity.com/lbnews/nl108/clipboard.htm)
mainwin 120 30 : titlebar "getMainwinTEXT (experimental)"
'** FormatMessageA (kernel32) struct lpSource, lpSource as long struct Arguments, Arguments as long
global nu$, cr$, dq$, nl2$, caption$ nul$ = chr$(0) : lf$ = chr$(10) : cr$ = chr$(13) : dq$ = chr$(34) : nl$ = cr$; lf$ : nl2$ = nl$; nl$
myApp$ = "getMainwinTEXT" : caption$ = " "; myApp$; cr$
print "Welcome to my getMainwinTEXT experiment!" print "Hope you will enjoy it..." print "Let's see if it work." print
global INPUT.KEYBOARD, KEYEVENTF.KEYUP, VK.A, VK.C INPUT.KEYBOARD = 1 : KEYEVENTF.KEYUP = hexdec("2") : VK.A = hexdec("41") : VK.C = hexdec("43")
scanCodeA = hexdec("1E") : scanCodeC = hexdec("2E")
'The dummy parameters are needed to fill up space that would otherwise be taken up by the other structs struct pInputs, _ type as ulong, _ wVk as word, _ wScan as word, _ dwFlags as ulong, _ time as ulong, _ dwExtraInfo as ulong, _ dummy1 as long, _ dummy2 as long
r = SendInput(_VK_CONTROL, "down", 0) r = SendInput(VK.A, "down", scanCodeA) r = SendInput(VK.A, "up", scanCodeA) r = SendInput(_VK_CONTROL, "up", 0)
r = SendInput(_VK_CONTROL, "down", 0) r = SendInput(VK.C, "down", scanCodeC) r = SendInput(VK.C, "up", scanCodeC) r = SendInput(_VK_CONTROL, "up", 0)
r = SendInput(_VK_CONTROL, "down", 0) r = SendInput(_VK_END, "down", 0) r = SendInput(_VK_END, "up", 0) r = SendInput(_VK_CONTROL, "up", 0)
if r then clipBoardText$ = getClipBoardText$() if len(clipBoardText$) then t$ = translate$("MAINWIN text successfully copied in the Windows clipboard!"); nl2$; _ translate$("See below"); ":"; nl2$; _ dq$; clipBoardText$; dq$ else t$ = translate$("MAINWIN text copy failed"); "." end if notice caption$; t$
end
[SendInput]
function SendInput(wVk, mode$, scanCode)
cInputs = 1
pInputs.type.struct = INPUT.KEYBOARD pInputs.wVk.struct = wVk pInputs.wScan.struct = scanCode
if mode$ = "up" then pInputs.dwFlags.struct = KEYEVENTF.KEYUP else pInputs.dwFlags.struct = 0
cbSize = len(pInputs.struct)
calldll #user32, "SendInput", _ cInputs as ulong, _ pInputs as struct, _ cbSize as long, _ SendInput as ulong
if SendInput = 0 then calldll #kernel32, "GetLastError", r as long r$ = "SendInput (#user32) = "; str$(r) notice caption$; formatMessage$(r$, r) end if
end function
[formatMessage]
function formatMessage$(source$, rc)
dwFlags = _FORMAT_MESSAGE_FROM_SYSTEM or _FORMAT_MESSAGE_ALLOCATE_BUFFER dwMessageId = rc
calldll #kernel32, "FormatMessageA", _ dwFlags as long, _ lpSource as struct, _ dwMessageId as long, _ dwLanguageId as long, _ lpBuffer$ as ptr, _ nSize as long, _ Arguments as struct, _ r as long
dwFlags = _FORMAT_MESSAGE_FROM_SYSTEM nSize = r + 1 lpBuffer$ = space$(nSize) + nul$
calldll #kernel32, "FormatMessageA", _ dwFlags as long, _ lpSource as struct, _ dwMessageId as long, _ dwLanguageId as long, _ lpBuffer$ as ptr, _ nSize as long, _ Arguments as struct, _ r as long
if r then formatMessage$ = source$; nl2$; trim$(lpBuffer$) else formatMessage$ = translate$("No further info is available"); "." end if
lpBuffer$ = ""
end function
[getClipboardData]
function getClipBoardText$() calldll #user32, "OpenClipboard", hWnd as long, r as boolean calldll #user32, "GetClipboardData", _CF_TEXT as long, hTxt as long calldll #user32, "CloseClipboard", r as boolean if hTxt then getClipBoardText$ = trim$(winstring(hTxt)) end function
[translate]
function translate$(text$) translate$ = text$ end function
Fabio
|
|
|
Post by Fabio Siciliano on Jun 12, 2020 8:34:06 GMT -5
Hello folks... just an update... the previous code seemed to work but... actually it wasn't. That's because, I realized, issuing a sequence of CTRL+A, CTRL+C does not mean "select all text and copy it into the clipboard" but "SAY THE WINDOWS PROCESS TO select all text and copy it into the clipboard"... this makes a big difference and in a MAINWIN the window process does it AFTER a WAIT or an END command, not before.
In fact, if you copy some text from another window and then run my code, you will get the text you copied before, not the one my code asked the window to copy into the clipboard by issuing the above sequence of CTRL+A, CTRL+C.
To solve it, a simple change was missing: a SCAN command must be coded just after each SendInput calldll when the return code was true (I mean, 1).
This way, everything works perfectly.
See you. Fabio
|
|
|
Post by Fabio Siciliano on Jun 12, 2020 9:56:08 GMT -5
Okay... here you can find the last update of my code... other than the SCAN add after SendInput went fine, I added another improvement. Because my code is playing with the clipboard content but I don't want my code to be intrusive and destructive with the activities of the user with other apps before mine, in my new code I implemented a save & restore functionality of the previous clipboard content, if any.
To test it, simply copy something in the clipboard before running my code and then, after it run and ended, paste it somewhere... you should get what you previously copied.
Enjoy it! Fabio
'** TEST program to show how to copy text from the MAINWIN into the Windows Clipboard (and retrieving it!) '** by Fabio Siciliano, June, 7th, 2020 (last update: June, 12th, 2020)
'** CREDITS: thanks to Chris Iverson (Administrator of Liberty BASIC Community Forum) who figured out how to deal with the INPUT struct and scan codes '** on June, 7th, 2020 (https://libertybasiccom.proboards.com/thread/1118/struggling-sendinput-api-function-user32?page=1&scrollTo=7815) ' '** Thanks also to Alice Watson for her very useful article "CLIPBOARD API DEMOS" (http://libertybasicuniversity.com/lbnews/nl108/clipboard.htm)
mainwin 120 30 : hmainwin = GetActiveWindow() : titlebar "getMainwinTEXT (experimental)"
'** FormatMessageA (kernel32) struct lpSource, lpSource as long struct Arguments, Arguments as long
global nu$, cr$, dq$, nl2$, caption$ nul$ = chr$(0) : lf$ = chr$(10) : cr$ = chr$(13) : dq$ = chr$(34) : nl$ = cr$; lf$ : nl2$ = nl$; nl$
myApp$ = "getMainwinTEXT" : caption$ = " "; myApp$; cr$
'** get the text previously copied in the clipboard, if any, to restore it before exiting old.clipboardText$ = getClipboardText$(hmainwin)
'** print something in the MAINWIN print "Welcome to my getMainwinTEXT experiment!" print "Hope you will enjoy it..." print "Let's see if it work."
global INPUT.KEYBOARD, KEYEVENTF.KEYUP, VK.A, VK.C INPUT.KEYBOARD = 1 : KEYEVENTF.KEYUP = hexdec("2") : VK.A = hexdec("41") : VK.C = hexdec("43")
scanCodeA = hexdec("1E") : scanCodeC = hexdec("2E")
'** the dummy parameters are needed to fill up space that would otherwise be taken up by the other structs struct pInputs, _ type as ulong, _ wVk as word, _ wScan as word, _ dwFlags as ulong, _ time as ulong, _ dwExtraInfo as ulong, _ dummy1 as long, _ dummy2 as long
'** send the window a sequence of CTRL+A, CTRL+C, END to select, copy into the clipboard and unselect the MAINWIN content r = SendInput(_VK_CONTROL, "down", 0) r = SendInput(VK.A, "down", scanCodeA) r = SendInput(VK.A, "up", scanCodeA) r = SendInput(_VK_CONTROL, "up", 0)
r = SendInput(_VK_CONTROL, "down", 0) r = SendInput(VK.C, "down", scanCodeC) r = SendInput(VK.C, "up", scanCodeC) r = SendInput(_VK_CONTROL, "up", 0)
r = SendInput(_VK_CONTROL, "down", 0) r = SendInput(_VK_END, "down", 0) r = SendInput(_VK_END, "up", 0) r = SendInput(_VK_CONTROL, "up", 0)
'** retrieve and show the text copied from the MAINWIN new.clipboardText$ = getClipboardText$(hmainwin) if len(new.clipboardText$) then t$ = translate$("MAINWIN text successfully copied in the Windows clipboard!"); nl2$; _ translate$("See below"); ":"; nl2$; _ dq$; new.clipboardText$; dq$ else t$ = translate$("MAINWIN text copy failed"); "." end if notice caption$; t$
'** restore the previous content of the clipboard, if any, so that this program is not intrusive to the work of other apps if len(new.clipboardText$) and len(old.clipboardText$) then r = setClipboardText(hmainwin, old.clipboardText$)
wait
[CloseClipboard]
function CloseClipboard() calldll #user32, "CloseClipboard", CloseClipboard as boolean end function
[EmptyClipboard]
function EmptyClipboard() calldll #user32, "EmptyClipboard", EmptyClipboard as boolean end function
[formatMessage]
function formatMessage$(source$, rc)
dwFlags = _FORMAT_MESSAGE_FROM_SYSTEM or _FORMAT_MESSAGE_ALLOCATE_BUFFER dwMessageId = rc
calldll #kernel32, "FormatMessageA", _ dwFlags as long, _ lpSource as struct, _ dwMessageId as long, _ dwLanguageId as long, _ lpBuffer$ as ptr, _ nSize as long, _ Arguments as struct, _ r as long
dwFlags = _FORMAT_MESSAGE_FROM_SYSTEM nSize = r + 1 lpBuffer$ = space$(nSize) + nul$
calldll #kernel32, "FormatMessageA", _ dwFlags as long, _ lpSource as struct, _ dwMessageId as long, _ dwLanguageId as long, _ lpBuffer$ as ptr, _ nSize as long, _ Arguments as struct, _ r as long
if r then formatMessage$ = source$; nl2$; trim$(lpBuffer$) else formatMessage$ = translate$("No further info is available"); "." end if
lpBuffer$ = ""
end function
[GetActiveWindow]
function GetActiveWindow() calldll #user32, "GetActiveWindow", GetActiveWindow as ulong end function
[getClipboardText]
function getClipboardText$(hWnd) clipboardIsOpen = OpenClipboard(hWnd) if clipboardIsOpen then calldll #user32, "GetClipboardData", _CF_TEXT as long, hTxt as long if hTxt then getClipboardText$ = trim$(winstring(hTxt)) r = CloseClipboard() end if end function
[GlobalAlloc]
function GlobalAlloc(type, dwBytes) calldll #kernel32, "GlobalAlloc", type as long, dwBytes as ulong, GlobalAlloc as long end function
[GlobalFree]
function GlobalFree(hMem) calldll #kernel32, "GlobalFree", hMem as ulong, GlobalFree as long end function
[GlobalLock]
function GlobalLock(hMem) calldll #kernel32, "GlobalLock", hMem as long, GlobalLock as long end function
[GlobalUnlock]
function GlobalUnlock(hMem) calldll #kernel32, "GlobalUnlock", hMem as long, GlobalUnlock as long end function
[OpenClipboard]
function OpenClipboard(hWnd) calldll #user32, "OpenClipboard", hWnd as long, OpenClipboard as boolean end function
[SendInput]
function SendInput(wVk, mode$, scanCode)
cInputs = 1
pInputs.type.struct = INPUT.KEYBOARD pInputs.wVk.struct = wVk pInputs.wScan.struct = scanCode
if mode$ = "up" then pInputs.dwFlags.struct = KEYEVENTF.KEYUP else pInputs.dwFlags.struct = 0
cbSize = len(pInputs.struct)
calldll #user32, "SendInput", _ cInputs as ulong, _ pInputs as struct, _ cbSize as long, _ SendInput as ulong
if SendInput = 0 then calldll #kernel32, "GetLastError", r as long r$ = "SendInput (#user32) = "; str$(r) notice caption$; formatMessage$(r$, r) else '***** without this, sent keystrokes are processed by the window only at end/wait, so the retrieved '***** text from the clipboard would be the previously copied, if any, not the current one! scan end if
end function
[setClipboardText]
function setClipboardText(hWnd, strText$) clipboardIsOpen = OpenClipboard(hWnd) if clipboardIsOpen then 'if len(strText$) = 0 then exit function strText$ = strText$; nul$ lngSize = len(strText$) + 1 ' allocate the needed memory hMemory = GlobalAlloc(_GMEM_MOVEABLE, lngSize) ' lock the object into memory lpMemory = GlobalLock(hMemory) ' move the string into the memory we locked calldll #kernel32, "RtlMoveMemory", lpMemory as ulong, strText$ as ptr, lngSize as long, ret as void ' don't send clipboard locked memory r = GlobalUnlock(hMemory) ' remove the current contents of the clipboard r = EmptyClipboard() ' add our string to the clipboard as text (if hSuccess > 0 then we have set the clipboard data) calldll #user32, "SetClipboardData", _CF_TEXT as long, hMemory as long, hSuccess as long ' free the allocated memory if hSuccess = 0 then r = GlobalFree(hMemory) r = CloseClipboard() setClipboardText = hSuccess end if end function
[translate]
function translate$(text$) translate$ = text$ end function
|
|
|
Post by Chris Iverson on Jun 12, 2020 12:06:28 GMT -5
I wouldn't bother restoring the clipboard contents. The clipboard is intended to be temporary, and if you don't restore it right, you can actually cause more problems.
I can prove it, too.
Open a Word document(or WordPad, if you don't have office), type some stuff it. Format it in special ways. Change the justification on some parts. Change the font on others. Change the font size. Use lists. Use tables. Use images.
Then do a select-all, copy, open a new file in word, and paste. Everything should copy over perfectly and identically.
Then do a select-all and copy again, then run your LB program. Open a new word document, and do another paste. You'll see that only the text got copied, and it lost all formatting.
The clipboard isn't just for text, but you told the clipboard previously to only copy the text, and then only gave the clipboard text back. All the formatting and image data was lost. And LB can't (easily) retrieve clipboard contents in other formats.
|
|
|
Post by Fabio Siciliano on Jun 24, 2020 12:06:06 GMT -5
Yes, I understand your point but, IMHO, it is a minor issue. As you told before, the clipboard is intended to be temporary. Just in case I'm working with two different applications, e.g. Word and my LB above app, if I copy something using the first one and then run the second one before using the text I copied, it would be completeley lost without bothering restoring the clipboard contents in my LB above app. IMHO it's better to keep the copied text available in the clipboard without formatting than loosing it completely.
|
|
|
Post by Chris Iverson on Jun 24, 2020 13:46:37 GMT -5
For your own personal use, that's fine. Set it up however it's convenient for you.
For applications that are intended to be distributed to other people, I will have to agree to disagree with you.
You claim you don't want your code to be "intrusive and destructive", but if you're changing clipboard contents without doing a full, proper backup and restore of the contents in all formats, that's exactly what you're being. (Also, it's rarely used, but it's possible for it to be technically impossible to restore clipboard contents, since there's a clipboard format in which the program supplying data doesn't generate the contents of the clipboard until it's actually asked for.)
If the user needed that proper data, and not just the text, they're going to have to make the copy again anyway. The issue your program causes is it makes it look like the third party program has a bug that's causing it to sometimes not copy data properly, instead of knowing that another program modified the clipboard. The user thinks the other program(Word, in this example) is buggy and broken, and possibly contacts the support team for that application, who have no idea what the problem is, and can't figure it out, because they don't know that another application is interfering with the clipboard.
If the user's going to have to copy the data again regardless, it should at least be clear that it wasn't a buggy copy that ruined the data in the first place.
I do appreciate the idea of restoring the clipboard if you need to utilize it for some sort of data interchange, and I can see the benefits of it, but if you can't fully do it properly(and LB doesn't have the capabilities to do so easily, since it would involve not just the Win32 API, but the COM API, which is much, much harder to use in LB), then you may end up accidentally causing more headaches to the end user by taking half-measures.
It's just something to evaluate if you're going to distribute your application. Again, for something that's for your own personal use, you know exactly what it's doing, and there's no potential for confusion. May as well make it as convenient for yourself as possible.
|
|
|
Post by Fabio Siciliano on Jul 26, 2020 16:32:49 GMT -5
Hi Chris, yes, by now it is for personal use only. The target was to resize automatically the mainwin to fit its content, I mean, to reduce it so that it is not bigger than needed. And, by the way, it works very well. Once the content is fully available to the program and the program itself is aware of the longest line, it is rather simple to resize the window. That said, just in case someday I would distribute this technology, I could give the user a clear alert saying that it could alter the clipboard content, if any, to plain text. Anyway, thank you very much for your answers and suggestions.
|
|