mirror of
https://github.com/chylex/TweetDuck.git
synced 2025-05-12 14:34:08 +02:00
Rewrite tweet screenshot functionality to use native methods
This commit is contained in:
parent
69ea242408
commit
563c856dd3
Core
Notification/Screenshot
Utils
@ -4,6 +4,9 @@
|
||||
using TweetDck.Core.Bridge;
|
||||
using TweetDck.Core.Controls;
|
||||
using TweetDck.Resources;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using TweetDck.Core.Utils;
|
||||
|
||||
namespace TweetDck.Core.Notification.Screenshot{
|
||||
sealed class FormNotificationScreenshotable : FormNotificationBase{
|
||||
@ -21,15 +24,30 @@ public void LoadNotificationForScreenshot(TweetNotification tweet, int width, in
|
||||
browser.LoadHtml(tweet.GenerateHtml(enableCustomCSS: false), "http://tweetdeck.twitter.com/?"+DateTime.Now.Ticks);
|
||||
|
||||
Location = ControlExtensions.InvisibleLocation;
|
||||
FormBorderStyle = Program.UserConfig.ShowScreenshotBorder ? FormBorderStyle.FixedToolWindow : FormBorderStyle.None;
|
||||
|
||||
SetNotificationSize(width, height);
|
||||
}
|
||||
|
||||
public void TakeScreenshotAndHide(){
|
||||
MoveToVisibleLocation();
|
||||
Activate();
|
||||
SendKeys.SendWait("%{PRTSC}");
|
||||
|
||||
bool border = Program.UserConfig.ShowScreenshotBorder;
|
||||
IntPtr context = NativeMethods.GetDeviceContext(this, border);
|
||||
|
||||
if (context == IntPtr.Zero){
|
||||
MessageBox.Show("Could not retrieve a graphics context handle for the notification window to take the screenshot.", "Screenshot Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
else{
|
||||
using(Bitmap bmp = new Bitmap(border ? Width : ClientSize.Width, border ? Height : ClientSize.Height, PixelFormat.Format32bppRgb)){
|
||||
try{
|
||||
NativeMethods.RenderSourceIntoBitmap(context, bmp);
|
||||
}finally{
|
||||
NativeMethods.ReleaseDeviceContext(this, context);
|
||||
}
|
||||
|
||||
Clipboard.SetImage(bmp);
|
||||
}
|
||||
}
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
|
@ -4,14 +4,11 @@
|
||||
|
||||
namespace TweetDck.Core.Notification.Screenshot{
|
||||
sealed class TweetScreenshotManager : IDisposable{
|
||||
private readonly FormBrowser browser;
|
||||
private readonly FormNotificationScreenshotable screenshot;
|
||||
private readonly Timer timeout;
|
||||
|
||||
public TweetScreenshotManager(FormBrowser browser){
|
||||
this.browser = browser;
|
||||
|
||||
this.screenshot = new FormNotificationScreenshotable(Callback, browser, NotificationFlags.DisableContextMenu | NotificationFlags.TopMost){
|
||||
public TweetScreenshotManager(Form owner){
|
||||
this.screenshot = new FormNotificationScreenshotable(Callback, owner, NotificationFlags.DisableContextMenu | NotificationFlags.TopMost){
|
||||
CanMoveWindow = () => false
|
||||
};
|
||||
|
||||
@ -31,10 +28,7 @@ private void Callback(){
|
||||
}
|
||||
|
||||
timeout.Stop();
|
||||
|
||||
browser.PauseNotification();
|
||||
screenshot.TakeScreenshotAndHide();
|
||||
browser.ResumeNotification();
|
||||
}
|
||||
|
||||
public void Dispose(){
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
|
||||
@ -45,6 +46,19 @@ private struct LASTINPUTINFO{
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool GetLastInputInfo(ref LASTINPUTINFO info);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern IntPtr GetWindowDC(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern IntPtr GetDC(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDC);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool BitBlt(IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, uint dwRop);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr SendMessage(IntPtr hWnd, uint msg, int wParam, IntPtr lParam);
|
||||
|
||||
@ -106,5 +120,25 @@ public static int GetIdleSeconds(){
|
||||
int seconds = (int)Math.Floor(TimeSpan.FromMilliseconds(ticks-info.dwTime).TotalSeconds);
|
||||
return Math.Max(0, seconds); // ignore rollover after several weeks of uptime
|
||||
}
|
||||
|
||||
public static IntPtr GetDeviceContext(Form form, bool includeBorder){
|
||||
return includeBorder ? GetWindowDC(form.Handle) : GetDC(form.Handle);
|
||||
}
|
||||
|
||||
public static void RenderSourceIntoBitmap(IntPtr source, Bitmap target){
|
||||
using(Graphics graphics = Graphics.FromImage(target)){
|
||||
IntPtr graphicsHandle = graphics.GetHdc();
|
||||
|
||||
try{
|
||||
BitBlt(graphicsHandle, 0, 0, target.Width, target.Height, source, 0, 0, 0x00CC0020);
|
||||
}finally{
|
||||
graphics.ReleaseHdc(graphicsHandle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void ReleaseDeviceContext(Form form, IntPtr ctx){
|
||||
ReleaseDC(form.Handle, ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user