Skip to content

Commit

Permalink
fix: 修复hdc释放错误问题
Browse files Browse the repository at this point in the history
  • Loading branch information
nashaofu committed Jan 26, 2024
1 parent 52f06a8 commit 4c12ea0
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 13 deletions.
28 changes: 20 additions & 8 deletions src/windows/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,39 @@ use windows::{
core::PCWSTR,
Win32::{
Foundation::HWND,
Graphics::Gdi::{CreateDCW, DeleteDC, DeleteObject, GetWindowDC, HBITMAP, HDC},
Graphics::Gdi::{CreateDCW, DeleteDC, DeleteObject, GetWindowDC, ReleaseDC, HBITMAP, HDC},
},
};

pub(super) struct BoxHDC(HDC);
pub(super) struct BoxHDC {
hdc: HDC,
hwnd: Option<HWND>,
}

impl Deref for BoxHDC {
type Target = HDC;
fn deref(&self) -> &Self::Target {
&self.0
&self.hdc
}
}

impl Drop for BoxHDC {
fn drop(&mut self) {
// ReleaseDC 与 DeleteDC 的区别
// https://learn.microsoft.com/zh-cn/windows/win32/api/winuser/nf-winuser-releasedc
unsafe {
DeleteDC(self.0);
if let Some(hwnd) = self.hwnd {
ReleaseDC(hwnd, self.hdc);
} else {
DeleteDC(self.hdc);
}
};
}
}

impl BoxHDC {
pub fn new(hdc: HDC) -> Self {
BoxHDC(hdc)
pub fn new(hdc: HDC, hwnd: Option<HWND>) -> Self {
BoxHDC { hdc, hwnd }
}
}

Expand All @@ -43,15 +52,17 @@ impl From<&[u16; 32]> for BoxHDC {
)
};

BoxHDC::new(hdc)
BoxHDC::new(hdc, None)
}
}

impl From<HWND> for BoxHDC {
fn from(hwnd: HWND) -> Self {
// GetWindowDC vs GetDC, GetDC 不会绘制窗口边框
// https://learn.microsoft.com/zh-cn/windows/win32/api/winuser/nf-winuser-getwindowdc
let hdc = unsafe { GetWindowDC(hwnd) };

BoxHDC::new(hdc)
BoxHDC::new(hdc, Some(hwnd))
}
}

Expand All @@ -66,6 +77,7 @@ impl Deref for BoxHBITMAP {

impl Drop for BoxHBITMAP {
fn drop(&mut self) {
// https://learn.microsoft.com/zh-cn/windows/win32/api/wingdi/nf-wingdi-createcompatiblebitmap
unsafe {
DeleteObject(self.0);
};
Expand Down
10 changes: 6 additions & 4 deletions src/windows/capture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,9 @@ pub fn capture_monitor(x: i32, y: i32, width: i32, height: i32) -> XCapResult<Rg
let hwnd = GetDesktopWindow();
let box_hdc_desktop_window = BoxHDC::from(hwnd);

// 内存中的HDC
let box_hdc_mem = BoxHDC::new(CreateCompatibleDC(*box_hdc_desktop_window));
// 内存中的HDC,使用 DeleteDC 函数释放
// https://learn.microsoft.com/zh-cn/windows/win32/api/wingdi/nf-wingdi-createcompatibledc
let box_hdc_mem = BoxHDC::new(CreateCompatibleDC(*box_hdc_desktop_window), None);
let box_h_bitmap = BoxHBITMAP::new(CreateCompatibleBitmap(
*box_hdc_desktop_window,
width,
Expand Down Expand Up @@ -103,8 +104,9 @@ pub fn capture_monitor(x: i32, y: i32, width: i32, height: i32) -> XCapResult<Rg
pub fn capture_window(hwnd: HWND, width: i32, height: i32) -> XCapResult<RgbaImage> {
unsafe {
let box_hdc_window: BoxHDC = BoxHDC::from(hwnd);
// 内存中的HDC
let box_hdc_mem = BoxHDC::new(CreateCompatibleDC(*box_hdc_window));
// 内存中的HDC,使用 DeleteDC 函数释放
// https://learn.microsoft.com/zh-cn/windows/win32/api/wingdi/nf-wingdi-createcompatibledc
let box_hdc_mem = BoxHDC::new(CreateCompatibleDC(*box_hdc_window), None);
let box_h_bitmap = BoxHBITMAP::new(CreateCompatibleBitmap(*box_hdc_window, width, height));

// 使用SelectObject函数将这个位图选择到DC中
Expand Down
2 changes: 1 addition & 1 deletion src/windows/impl_monitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::error::{XCapError, XCapResult};

use super::{boxed::BoxHDC, capture::capture_monitor, utils::wide_string_to_string};

// A函数与W函数区别
// A 函数与 W 函数区别
// https://learn.microsoft.com/zh-cn/windows/win32/learnwin32/working-with-strings

#[derive(Debug, Clone)]
Expand Down

0 comments on commit 4c12ea0

Please sign in to comment.