简体   繁体   中英

Contents of clipboard are only available AFTER I use a MessageBox.Show(“…”)

I have an application that after a hotkey combo it in effect "sends" a Ctrl+C to the foreground window, to send the selected text to the clipboard. Then I need to get the text from the clipboard. The code to do so is the following:

[DllImport("user32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);

[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr GetForegroundWindow();

[DllImport("user32.dll")]
private static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, uint dwExtraInfo);

private void CopyHighlighted()
{
    uint KEYEVENTF_KEYUP = 2;
    byte VK_CONTROL = 0x11;
    SetForegroundWindow(GetForegroundWindow());
    keybd_event(VK_CONTROL, 0, 0, 0);
    keybd_event(0x43, 0, 0, 0); 
    keybd_event(0x43, 0, KEYEVENTF_KEYUP, 0);
    keybd_event(VK_CONTROL, 0x9d, KEYEVENTF_KEYUP, 0);

    bool containsStuff = (Clipboard.ContainsAudio() || Clipboard.ContainsFileDropList() || Clipboard.ContainsImage() || Clipboard.ContainsText());

    //The behavior changing MessageBox:
    //MessageBox.Show("the clipboard contains some data: " + containsStuff.ToString());

    string rawNumber = Clipboard.GetText();
    MessageBox.Show("raw contents of clipboard " + Environment.NewLine + rawNumber);
}

If the MessageBox is commented in, I get a popup that says "the clipboard contains some data: False". Which is very odd because the next popup says "raw contents of clipboard Clipboard.ContainsText() returns false...but sure enough rawNumber does contain the expected text.

BUT when I comment the first MessageBox out, I get only the 1 popup (as expected), but it says only "raw contents of clipboard " and rawNumber is an empty string.

Why does the inclusion of this intermediate MessageBox cause me to be able to get the clipboard text? And why prior to this does Clipboard.ContainsText() return false? Any help in understanding this, as well as getting it to function with NO MessageBox es would be great.

Try checking for the Clipboard Sequence Number changing:

Define the import:

[DllImport("user32.dll")]
static extern uint GetClipboardSequenceNumber();

Use it:

System.Threading.Thread.Sleep(5000);   // Give me time to switch windows
uint KEYEVENTF_KEYUP = 2;
byte VK_CONTROL = 0x11;
SetForegroundWindow(GetForegroundWindow());
keybd_event(VK_CONTROL, 0, 0, 0);
keybd_event(0x43, 0, 0, 0);
keybd_event(0x43, 0, KEYEVENTF_KEYUP, 0);
keybd_event(VK_CONTROL, 0x9d, KEYEVENTF_KEYUP, 0);

uint startClip = GetClipboardSequenceNumber();
uint nextClip = startClip;

while (nextClip == startClip)
{
    nextClip = GetClipboardSequenceNumber();
}

string rawNumber = Clipboard.GetText();
MessageBox.Show("raw contents of clipboard " + Environment.NewLine + rawNumber);

You should probably do this work in a non-ui thread and then event it. You may also want to throttle this code so it is not constantly calling the API.

I'm copying things out of Notepad (and other various apps) just fine when I move the mouse into my PictureBox with this simple code:

    private void pictureBox1_MouseEnter(object sender, EventArgs e)
    {
        SendKeys.SendWait("^c");
        if (Clipboard.ContainsText())
        {
            label1.Text = Clipboard.GetText();
        }
    }

Running Windows 8.1 x64 with an Admin account.

keybd_event puts events in the queue, but they are not processed until your code finishes. If you put

Application.DoEvents();

after the keydb_event calls then the keyboard events should get processed. I suspect Thread.Sleep() won't work because it just sleeps, but does not process waiting events.

The first call to MessageBox does allow events to run, thus after the MessageBox, there is stuff in the clipboard. Using SendKeys.SendWait() will work, but SendKeys.Send won't because SendWait waits for the key board events to be processed, whereas SendKeys.Send doesn't.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM