GetDlgItem

本文详细介绍了GetDlgItem函数的使用方法及注意事项,解释了其在对话框及非对话框环境下的不同应用方式,并提供了如何正确调用该函数以避免错误的指导。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

GetDlgItem(IDC_..)是一个非静态方法,意思是你对话框内获取该控件指针,所以这里不需要获取对话框句柄,也就是说你如果在非对话框窗口里面调用这个方法就肯定会出错
GetDlgItem(HWND hWnd, IDC_..)是一个静态方法,它是一个让你指定从哪个对话框里获取控件指针
举个例子:你调用了上厕所这个函数,如果你在家里的话肯定是在自己家里上厕所,所以不需要知道在哪里上厕所(hwnd)
如果你在室外那么上厕所就一定要选一个地方(hwnd)。
如果说你上厕所的地方都不是一个房间,那么肯定会报错嘛,因为你在随地大小便,哈哈
所以你先搞清楚这两个函数的使用环境区别
再者,你问这个问题说明了你还没有搞清楚对话框是一个什么东西,建议学习一下深入浅出MFC

 

 

 

GetDlgItem

  函数功能:该函数检索指定的对话框中的控制句柄。   函数原型:HWND GetDlgltem(HWND hDlg,int nlDDlgltem);   参数:   hDlg:标识含有控制的对话框。   nlDDlgltem:指定将被检索的控制标识符。   返回值:如果函数调用成功则返回值为给定控制的窗口句柄。如果函数调用失败,则返回值为NULL,表示为一个无效的对话框句柄或一个不存在的控制。若想获得更多错误信息,请调用GetLastError函数。   备注:可以通过使用任何父子窗口对来使用GetDlgltem函数,而不仅只是对话框。只要hDlg参数指定一个父窗口,且子窗口有一个独立的标识符(象CreateWindow中hMenu参数指定的或创建子窗口的CreateWindowEx指定的那样),GetDlgltem就会返回一个有效的句柄到子窗口。   Windows CE:GetDlgltem函数只为对话框中的直接于控制工作,它不通过嵌套的对话框来搜寻。   速查:Windows NT:3.1及以上版本;Windows:95及以上版本;Windows CE:1.0及以上版本;头文件:winuser.h;库文件:user32.lib。
// B2saomiaotuxiangchuangkou.cpp : 实现文件 // #include "stdafx.h" #include "Imageprocessing.h" #include "B2saomiaotuxiangchuangkou.h" #include "afxdialogex.h" #include <string> #include <chrono> #include <Gdiplus.h> #include <shlwapi.h> #pragma comment(lib, "Gdiplus.lib") #pragma comment(lib, "shlwapi.lib") #pragma comment(lib, "Shell32.lib") // B2saomiaotuxiangchuangkou 对话框 IMPLEMENT_DYNAMIC(B2saomiaotuxiangchuangkou, CDialogEx) B2saomiaotuxiangchuangkou::B2saomiaotuxiangchuangkou(CWnd* pParent /*=NULL*/) : CDialogEx(IDD_B2saomiaotuxiangchuangkou, pParent) { } B2saomiaotuxiangchuangkou::~B2saomiaotuxiangchuangkou() { Cleanup(); } void B2saomiaotuxiangchuangkou::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Control(pDX, IDC_EDIT_FOLDER_PATH, m_editFolderPath); DDX_Control(pDX, IDC_LIST_IMAGES, m_listImages); DDX_Control(pDX, IDC_COMBO_SAVE_OPTION, m_saveOption); DDX_Control(pDX, IDC_BUTTON_START, m_btnStart); DDX_Control(pDX, IDC_BUTTON_PAUSE, m_btnPause); DDX_Control(pDX, IDC_BUTTON_STOP, m_btnStop); DDX_Control(pDX, IDC_BUTTON_RESET, m_btnReset); DDX_Control(pDX, IDC_BUTTON_SELECT_FOLDER, m_btnSelectFolder); DDX_Control(pDX, IDC_PROGRESS_TOTAL, m_totalProgress); DDX_Control(pDX, IDC_PROGRESS_FILE, m_fileProgress); DDX_Control(pDX, IDC_STATIC_ORIGINAL_IMAGE, m_originalImage); DDX_Control(pDX, IDC_STATIC_PROCESSED_IMAGE, m_processedImage); DDX_Control(pDX, IDC_EDIT2, m_editSavePath); } BEGIN_MESSAGE_MAP(B2saomiaotuxiangchuangkou, CDialogEx) ON_WM_SIZE() ON_BN_CLICKED(IDC_BUTTON_SELECT_FOLDER, &B2saomiaotuxiangchuangkou::OnBnClickedButtonSelectFolder) ON_BN_CLICKED(IDC_BUTTON_START, &B2saomiaotuxiangchuangkou::OnBnClickedButtonStart) ON_BN_CLICKED(IDC_BUTTON_PAUSE, &B2saomiaotuxiangchuangkou::OnBnClickedButtonPause) ON_BN_CLICKED(IDC_BUTTON_STOP, &B2saomiaotuxiangchuangkou::OnBnClickedButtonStop) ON_BN_CLICKED(IDC_BUTTON_RESET, &B2saomiaotuxiangchuangkou::OnBnClickedButtonReset) ON_CBN_SELCHANGE(IDC_COMBO_SAVE_OPTION, &B2saomiaotuxiangchuangkou::OnCbnSelchangeComboSaveOption) ON_WM_TIMER() ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST_IMAGES, &B2saomiaotuxiangchuangkou::OnLvnItemchangedListImages) ON_MESSAGE(WM_LOAD_FIRST_IMAGE, &B2saomiaotuxiangchuangkou::OnLoadFirstImageMessage) ON_MESSAGE(WM_UPDATE_DISPLAY_IMAGE, &B2saomiaotuxiangchuangkou::OnUpdateDisplayImage) ON_WM_MOUSEWHEEL() // 添加鼠标滚轮消息映射 ON_WM_ERASEBKGND() END_MESSAGE_MAP() BOOL B2saomiaotuxiangchuangkou::OnInitDialog() { CDialogEx::OnInitDialog(); m_listImages.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES); m_listImages.InsertColumn(0, _T("文件名"), LVCFMT_LEFT, 200); m_listImages.InsertColumn(1, _T("大小"), LVCFMT_RIGHT, 100); m_listImages.InsertColumn(2, _T("类型"), LVCFMT_LEFT, 100); m_saveOption.AddString(_T("覆盖原图")); m_saveOption.AddString(_T("新路径")); m_saveOption.SetCurSel(0); m_totalProgress.SetRange(0, 100); m_fileProgress.SetRange(0, 100); m_totalProgress.SetPos(0); m_fileProgress.SetPos(0); m_btnPause.EnableWindow(FALSE); m_btnStop.EnableWindow(FALSE); m_btnReset.EnableWindow(FALSE); m_originalImage.ModifyStyle(0, SS_BITMAP | SS_CENTERIMAGE); m_processedImage.ModifyStyle(0, SS_BITMAP| SS_CENTERIMAGE); m_originalImage.GetWindowRect(&m_originalRect); ScreenToClient(&m_originalRect); m_processedImage.GetWindowRect(&m_processedRect); ScreenToClient(&m_processedRect); Gdiplus::GdiplusStartupInput gdiplusInput; ULONG_PTR gdiplusToken; Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusInput, NULL); if (!m_folderPath.IsEmpty()) { PostMessage(WM_LOAD_FIRST_IMAGE, 0, 0); } return TRUE; } void B2saomiaotuxiangchuangkou::SetControlPosition(CWnd* pCtrl, int x, int y, int width, int height) { if (pCtrl) { CRect rect(x, y, x + width, y + height); pCtrl->MoveWindow(rect); } } void B2saomiaotuxiangchuangkou::AdjustLayoutWhenResized() { CRect clientRect; GetClientRect(&clientRect); int cx = clientRect.Width(); int cy = clientRect.Height(); // 获取屏幕尺寸(可选,若需要基于屏幕比例布局) int sW = GetSystemMetrics(SM_CXSCREEN); int sH = GetSystemMetrics(SM_CYSCREEN); int pc_W1 = (cx - 530) / 3;//图像显示控件宽 int pc_H1;//图像显示控件高 int pc_W2 = (cy - 530) / 3 * 2;//图像显示控件宽 int pc_H2;//图像显示控件高 // 示例:调整子界面中控件的位置(类似你提供的代码) SetControlPosition(GetDlgItem(IDC_STATIC1), 0, 5, 80, 30); /**/ SetControlPosition(GetDlgItem(IDC_STATIC2), 0, 50, 80, 30); /**/SetControlPosition(GetDlgItem(IDC_EDIT_FOLDER_PATH), 85, 43, 280, 30); /**/SetControlPosition(GetDlgItem(IDC_BUTTON_SELECT_FOLDER), 366, 44, 70, 30); /**/SetControlPosition(GetDlgItem(IDC_BUTTON_START), 440, 43, 70, 30);/**/SetControlPosition(GetDlgItem(IDC_STATIC_ORIGINAL_IMAGE), 530, 5, pc_W1 - 1, 490);/**/SetControlPosition(GetDlgItem(IDC_STATIC_PROCESSED_IMAGE), 530 + pc_W1 + 2, 5, 2 * pc_W1 - 5, cy - 10); SetControlPosition(GetDlgItem(IDC_STATIC3), 0, 90, 80, 30); /**/SetControlPosition(GetDlgItem(IDC_EDIT2), 85, 83, 280, 30); /**/SetControlPosition(GetDlgItem(IDC_COMBO_SAVE_OPTION), 366, 89, 70, 30); /**/SetControlPosition(GetDlgItem(IDC_BUTTON_PAUSE), 440, 84, 70, 30); SetControlPosition(GetDlgItem(IDC_STATIC4), 0, 155, 80, 30); /**/ /**/SetControlPosition(GetDlgItem(IDC_BUTTON_STOP), 440, 124, 70, 30); SetControlPosition(GetDlgItem(IDC_STATIC6), 0, 200, 80, 30); /**/SetControlPosition(GetDlgItem(IDC_PROGRESS_TOTAL), 85, 197, 280, 20); /**/SetControlPosition(GetDlgItem(IDC_BUTTON_RESET), 440, 164, 70, 30); SetControlPosition(GetDlgItem(IDC_STATIC7), 0, 240, 80, 30); /**/SetControlPosition(GetDlgItem(IDC_PROGRESS_FILE), 85, 237, 180, 20); SetControlPosition(GetDlgItem(IDC_STATIC8), 0, 305, 80, 30); /**/ /*SetControlPosition(GetDlgItem(IDC_STATIC8), 0, 305, 80, 30); /**/ /*SetControlPosition(GetDlgItem(IDC_STATIC8), 0, 305, 80, 30);*/ /**/ SetControlPosition(GetDlgItem(IDC_LIST_IMAGES), 0, 500, 530 + pc_W1 - 1, cy - 500 - 5); /**/ } void B2saomiaotuxiangchuangkou::OnSize(UINT nType, int cx, int cy) { CDialogEx::OnSize(nType, cx, cy); if (nType != SIZE_MINIMIZED) { AdjustLayoutWhenResized(); } } // 在实现文件中添加函数实现 void B2saomiaotuxiangchuangkou::LoadFilesIntoListControl() { // 清空列表 m_listImages.DeleteAllItems(); m_imageFiles.clear(); m_imageLoaded = false; m_firstLoadCompleted = false; // 获取文件夹中的所有文件 std::vector<CString> files; CString searchPath = m_folderPath + _T("\\*.*"); WIN32_FIND_DATA findFileData; HANDLE hFind = FindFirstFile(searchPath, &findFileData); if (hFind != INVALID_HANDLE_VALUE) { do { if (!(findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { CString fileName = findFileData.cFileName; CString ext = fileName.Right(4).MakeLower(); if (ext == _T(".jpg") || ext == _T(".jpeg") || ext == _T(".png") || ext == _T(".bmp") || ext == _T(".tif") || ext == _T(".tiff")) { files.push_back(fileName); } } } while (FindNextFile(hFind, &findFileData)); FindClose(hFind); } // 使用 StrCmpLogicalW 进行自然排序 std::sort(files.begin(), files.end(), [](const CString& a, const CString& b) { return StrCmpLogicalW(a, b) < 0; }); // 将排序后的文件添加到列表控件 for (size_t i = 0; i < files.size(); ++i) { CString fileName = files[i]; CString filePath = m_folderPath + _T("\\") + fileName; m_imageFiles.push_back(filePath); // 添加到列表控件 int nIndex = m_listImages.InsertItem(i, fileName); // 获取文件大小 WIN32_FILE_ATTRIBUTE_DATA fad; ULONGLONG fileSize = 0; if (GetFileAttributesEx(filePath, GetFileExInfoStandard, &fad)) { fileSize = ((ULONGLONG)fad.nFileSizeHigh << 32) | fad.nFileSizeLow; } CString sizeStr; if (fileSize < 1024) sizeStr.Format(_T("%d B"), fileSize); else if (fileSize < 1024 * 1024) sizeStr.Format(_T("%.2f KB"), fileSize / 1024.0); else sizeStr.Format(_T("%.2f MB"), fileSize / (1024.0 * 1024.0)); m_listImages.SetItemText(nIndex, 1, sizeStr); // 文件类型 CString typeStr = fileName.Right(4).Mid(1).MakeUpper(); m_listImages.SetItemText(nIndex, 2, typeStr); } } void B2saomiaotuxiangchuangkou::OnBnClickedButtonSelectFolder() { CFolderPickerDialog dlg; if (dlg.DoModal() == IDOK) { m_folderPath = dlg.GetFolderPath(); m_editFolderPath.SetWindowText(m_folderPath); // 使用新的方法加载文件到列表控件 LoadFilesIntoListControl(); // 更新保存路径显示 OnCbnSelchangeComboSaveOption(); // 设置按钮状态 m_btnStart.EnableWindow(!m_imageFiles.empty()); // 显示第一张图片 if (!m_imageFiles.empty()) { m_listImages.SetItemState(0, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); m_listImages.EnsureVisible(0, FALSE); m_listImages.UpdateWindow(); PostMessage(WM_LOAD_FIRST_IMAGE, 0, 0); } } } LRESULT B2saomiaotuxiangchuangkou::OnLoadFirstImageMessage(WPARAM wParam, LPARAM lParam) { DisplayFirstImage(); return 0; } void B2saomiaotuxiangchuangkou::DisplayFirstImage() { if (m_imageFiles.empty()) return; CString filePath = m_imageFiles[0]; if (!LoadImageToControl(filePath, IDC_STATIC_ORIGINAL_IMAGE)) { m_loadMode = (m_loadMode == MODE_OPENCV) ? MODE_GDIPlus : MODE_OPENCV; if (!LoadImageToControl(filePath, IDC_STATIC_ORIGINAL_IMAGE)) { return; } } m_firstImageLoaded = true; m_firstLoadCompleted = true; m_imageLoaded = true; CWnd* pProcessed = GetDlgItem(IDC_STATIC_PROCESSED_IMAGE); if (pProcessed) { auto pStatic = reinterpret_cast<CStatic*>(pProcessed); HBITMAP hOldBmp = pStatic->GetBitmap(); if (hOldBmp) { DeleteObject(hOldBmp); pStatic->SetBitmap(NULL); } } } bool B2saomiaotuxiangchuangkou::LoadImageToControl(const CString& filePath, UINT controlID) { std::lock_guard<std::mutex> lock(m_imageMutex); DWORD fileAttr = GetFileAttributes(filePath); if (fileAttr == INVALID_FILE_ATTRIBUTES) { return false; } HBITMAP hBitmap = NULL; if (m_loadMode == MODE_OPENCV) { hBitmap = LoadImageWithOpenCV(filePath); } else { hBitmap = LoadImageWithGDIPlus(filePath); } if (!hBitmap) { return false; } CWnd* pWnd = GetDlgItem(controlID); if (pWnd) { CStatic* pStatic = dynamic_cast<CStatic*>(pWnd); if (pStatic) { HBITMAP oldBmp = pStatic->GetBitmap(); if (oldBmp) DeleteObject(oldBmp); pStatic->SetBitmap(hBitmap); pStatic->Invalidate(); return true; } } DeleteObject(hBitmap); return false; } // 禁用鼠标滚轮缩放功能 BOOL B2saomiaotuxiangchuangkou::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) { // 直接返回TRUE,阻止滚轮缩放 return TRUE; } // 修改 LoadImageWithOpenCV 函数 HBITMAP B2saomiaotuxiangchuangkou::LoadImageWithOpenCV(const CString& filePath) { cv::Mat img; #ifdef _UNICODE int len = WideCharToMultiByte(CP_UTF8, 0, filePath, -1, NULL, 0, NULL, NULL); std::vector<char> utf8Buf(len); WideCharToMultiByte(CP_UTF8, 0, filePath, -1, utf8Buf.data(), len, NULL, NULL); img = cv::imread(utf8Buf.data(), cv::IMREAD_COLOR); #else img = cv::imread(CW2A(filePath), cv::IMREAD_COLOR); #endif if (img.empty()) { return NULL; } // 关键修改:添加BGR到RGB的颜色空间转换 cv::cvtColor(img, img, cv::COLOR_BGR2RGB); CRect rect; m_originalImage.GetClientRect(&rect); int dstWidth = rect.Width(); int dstHeight = rect.Height(); // 计算缩放比例和位置 double ratio = std::min(static_cast<double>(dstWidth) / img.cols, static_cast<double>(dstHeight) / img.rows); int drawWidth = static_cast<int>(img.cols * ratio); int drawHeight = static_cast<int>(img.rows * ratio); int x = (dstWidth - drawWidth) / 2; int y = (dstHeight - drawHeight) / 2; // 创建目标位图 HDC hdcScreen = ::GetDC(NULL); HBITMAP hBitmap = CreateCompatibleBitmap(hdcScreen, dstWidth, dstHeight); HDC hdcMem = CreateCompatibleDC(hdcScreen); HBITMAP hOldBmp = (HBITMAP)SelectObject(hdcMem, hBitmap); // 填充白色背景 HBRUSH hBrush = CreateSolidBrush(RGB(255, 255, 255)); RECT rc = { 0, 0, dstWidth, dstHeight }; FillRect(hdcMem, &rc, hBrush); DeleteObject(hBrush); // 创建缩放后的图像 - 使用高质量缩放算法 cv::Mat resized; cv::resize(img, resized, cv::Size(drawWidth, drawHeight), 0, 0, cv::INTER_AREA); // 转换为 BITMAPINFO BITMAPINFOHEADER bmiHeader = { 0 }; bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmiHeader.biWidth = resized.cols; bmiHeader.biHeight = -resized.rows; // 负号表示从上到下的位图 bmiHeader.biPlanes = 1; bmiHeader.biBitCount = 24; bmiHeader.biCompression = BI_RGB; // 在目标DC上绘制图像(确保居中) SetStretchBltMode(hdcMem, HALFTONE); StretchDIBits( hdcMem, x, y, drawWidth, drawHeight, // 目标位置和大小 0, 0, resized.cols, resized.rows, // 源位置和大小 resized.data, (BITMAPINFO*)&bmiHeader, DIB_RGB_COLORS, SRCCOPY ); // 清理资源 SelectObject(hdcMem, hOldBmp); DeleteDC(hdcMem); ::ReleaseDC(NULL, hdcScreen); return hBitmap; } //// 修改 MatToBitmap 函数(确保其他地方的转换也正确) //HBITMAP B2saomiaotuxiangchuangkou::MatToBitmap(cv::Mat& mat) //{ // if (mat.empty()) return NULL; // // cv::Mat rgb; // // 添加颜色空间转换 // if (mat.channels() == 1) { // cv::cvtColor(mat, rgb, cv::COLOR_GRAY2BGR); // } // else if (mat.channels() == 3) { // cv::cvtColor(mat, rgb, cv::COLOR_BGR2RGB); // 关键修改 // } // else if (mat.channels() == 4) { // cv::cvtColor(mat, rgb, cv::COLOR_BGRA2BGR); // } // else { // rgb = mat; // } // // BITMAPINFOHEADER bmiHeader; // bmiHeader.biSize = sizeof(BITMAPINFOHEADER); // bmiHeader.biWidth = rgb.cols; // bmiHeader.biHeight = -rgb.rows; // bmiHeader.biPlanes = 1; // bmiHeader.biBitCount = 24; // bmiHeader.biCompression = BI_RGB; // bmiHeader.biSizeImage = 0; // bmiHeader.biXPelsPerMeter = 0; // bmiHeader.biYPelsPerMeter = 0; // bmiHeader.biClrUsed = 0; // bmiHeader.biClrImportant = 0; // // HDC hDC = ::GetDC(NULL); // HBITMAP hBitmap = CreateDIBitmap(hDC, &bmiHeader, CBM_INIT, // rgb.data, (BITMAPINFO*)&bmiHeader, DIB_RGB_COLORS); // ::ReleaseDC(NULL, hDC); // // return hBitmap; //} // 添加背景擦除处理,防止闪烁 BOOL B2saomiaotuxiangchuangkou::OnEraseBkgnd(CDC* pDC) { // 获取客户区矩形 CRect rect; GetClientRect(&rect); // 用白色填充背景 CBrush brush(RGB(255, 255, 255)); pDC->FillRect(&rect, &brush); return TRUE; // 返回TRUE表示我们已经擦除了背景 } //HBITMAP B2saomiaotuxiangchuangkou::LoadImageWithGDIPlus(const CString& filePath) { // Gdiplus::Image image(filePath); // if (image.GetLastStatus() != Gdiplus::Ok) return NULL; // // // 获取控件尺寸 // CRect rect; // m_originalImage.GetClientRect(&rect); // int controlWidth = rect.Width(); // int controlHeight = rect.Height(); // // // 计算缩放比例 // int srcWidth = image.GetWidth(); // int srcHeight = image.GetHeight(); // double ratio = std::min( // static_cast<double>(controlWidth) / srcWidth, // static_cast<double>(controlHeight) / srcHeight // ); // int drawWidth = static_cast<int>(srcWidth * ratio); // int drawHeight = static_cast<int>(srcHeight * ratio); // // // 计算起始坐标(如需左上角,设为 0) // int x = (controlWidth - drawWidth) / 2; // 水平居中(可改为 0) // int y = (controlHeight - drawHeight) / 2; // 垂直居中(可改为 0) // // // 创建位图并绘制 // Gdiplus::Bitmap bitmap(controlWidth, controlHeight, PixelFormat32bppARGB); // Gdiplus::Graphics graphics(&bitmap); // graphics.SetSmoothingMode(Gdiplus::SmoothingModeHighQuality); // graphics.Clear(Gdiplus::Color(255, 255, 255)); // 白色背景 // // // 关键:从 (x,y) 开始绘制图像 // graphics.DrawImage( // &image, // x, y, // drawWidth, drawHeight // ); // // // 获取 HBITMAP 句柄 // HBITMAP hBitmap = NULL; // bitmap.GetHBITMAP(Gdiplus::Color::White, &hBitmap); // return hBitmap; //} HBITMAP B2saomiaotuxiangchuangkou::LoadImageWithGDIPlus(const CString& filePath) { Gdiplus::Image image(filePath); if (image.GetLastStatus() != Gdiplus::Ok) { return NULL; } CRect rect; m_originalImage.GetClientRect(&rect); int ctrlWidth = rect.Width(); int ctrlHeight = rect.Height(); int srcWidth = image.GetWidth(); int srcHeight = image.GetHeight(); // 计算缩放比例(保持原图比例) double scale = std::min((double)ctrlWidth / srcWidth, (double)ctrlHeight / srcHeight); int drawWidth = (int)(srcWidth * scale); int drawHeight = (int)(srcHeight * scale); // 原图目标点(如中心点) int srcTargetX = srcWidth / 2; // 原图中心点X int srcTargetY = srcHeight / 2; // 原图中心点Y // 控件中心点 int ctrlCenterX = ctrlWidth / 2; int ctrlCenterY = ctrlHeight / 2; // 计算绘制起点(使原图目标点对齐控件中心点) int x = ctrlCenterX - srcTargetX * scale; int y = ctrlCenterY - srcTargetY * scale; Gdiplus::Bitmap bitmap(ctrlWidth, ctrlHeight, PixelFormat32bppARGB); Gdiplus::Graphics graphics(&bitmap); graphics.SetSmoothingMode(Gdiplus::SmoothingModeHighQuality); // 绘制图像(从原图(0,0)开始,按新起点绘制) graphics.DrawImage(&image, x, y, drawWidth, drawHeight); HBITMAP hBitmap = NULL; bitmap.GetHBITMAP(Gdiplus::Color::White, &hBitmap); return hBitmap; } HBITMAP B2saomiaotuxiangchuangkou::MatToBitmap(cv::Mat& mat) { if (mat.empty()) return NULL; cv::Mat bgr; if (mat.channels() == 1) { cv::cvtColor(mat, bgr, cv::COLOR_GRAY2BGR); } else if (mat.channels() == 4) { cv::cvtColor(mat, bgr, cv::COLOR_BGRA2BGR); } else { bgr = mat; } // 确保图像尺寸正确 if (bgr.rows <= 0 || bgr.cols <= 0) { return NULL; } BITMAPINFOHEADER bmiHeader; bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmiHeader.biWidth = bgr.cols; bmiHeader.biHeight = -bgr.rows; // 负号表示从下往上绘制 bmiHeader.biPlanes = 1; bmiHeader.biBitCount = 24; bmiHeader.biCompression = BI_RGB; bmiHeader.biSizeImage = 0; bmiHeader.biXPelsPerMeter = 0; bmiHeader.biYPelsPerMeter = 0; bmiHeader.biClrUsed = 0; bmiHeader.biClrImportant = 0; HDC hDC = ::GetDC(NULL); HBITMAP hBitmap = CreateDIBitmap(hDC, &bmiHeader, CBM_INIT, bgr.data, (BITMAPINFO*)&bmiHeader, DIB_RGB_COLORS); ::ReleaseDC(NULL, hDC); return hBitmap; } void B2saomiaotuxiangchuangkou::OnCbnSelchangeComboSaveOption() { int option = m_saveOption.GetCurSel(); if (option == 0) { m_savePath = m_folderPath; m_editSavePath.SetWindowText(m_savePath); } else if (option == 1) { if (m_savePath.IsEmpty() || m_savePath == m_folderPath) { CFolderPickerDialog dlg; if (dlg.DoModal() == IDOK) { m_savePath = dlg.GetFolderPath(); m_editSavePath.SetWindowText(m_savePath); } else { m_saveOption.SetCurSel(0); m_savePath = m_folderPath; m_editSavePath.SetWindowText(m_savePath); } } } } void B2saomiaotuxiangchuangkou::OnBnClickedButtonStart() { if (m_folderPath.IsEmpty()) { AfxMessageBox(_T("请先选择文件夹!")); return; } if (m_imageFiles.empty()) { AfxMessageBox(_T("文件夹中没有图像文件!")); return; } if (m_saveOption.GetCurSel() == 1 && m_savePath.IsEmpty()) { AfxMessageBox(_T("请先选择保存路径!")); return; } if (m_saveOption.GetCurSel() == 0) { CreateBackup(); } m_processing = true; m_paused = false; m_stopped = false; m_currentIndex = 0; m_btnStart.EnableWindow(FALSE); m_btnPause.EnableWindow(TRUE); m_btnStop.EnableWindow(TRUE); m_btnReset.EnableWindow(FALSE); m_totalProgress.SetPos(0); m_fileProgress.SetPos(0); if (m_processingThread.joinable()) { m_processingThread.join(); } m_processingThread = std::thread(&B2saomiaotuxiangchuangkou::ProcessImages, this); SetTimer(1, 100, NULL); } void B2saomiaotuxiangchuangkou::OnBnClickedButtonPause() { m_paused = !m_paused; m_btnPause.SetWindowText(m_paused ? _T("继续") : _T("暂停")); } void B2saomiaotuxiangchuangkou::OnBnClickedButtonStop() { m_stopped = true; m_processing = false; m_btnStart.EnableWindow(TRUE); m_btnPause.EnableWindow(FALSE); m_btnStop.EnableWindow(FALSE); m_btnReset.EnableWindow(TRUE); if (m_processingThread.joinable()) { m_processingThread.join(); } KillTimer(1); } void B2saomiaotuxiangchuangkou::OnBnClickedButtonReset() { OnBnClickedButtonStop(); if (m_saveOption.GetCurSel() == 0 && !m_backupPath.IsEmpty()) { RestoreBackup(); } m_currentIndex = 0; m_totalProgress.SetPos(0); m_fileProgress.SetPos(0); m_backupPath.Empty(); m_btnReset.EnableWindow(FALSE); if (!m_imageFiles.empty()) { m_listImages.SetItemState(0, LVIS_SELECTED, LVIS_SELECTED); PostMessage(WM_LOAD_FIRST_IMAGE, 0, 0); } } void B2saomiaotuxiangchuangkou::OnTimer(UINT_PTR nIDEvent) { if (nIDEvent == 1) { UpdateProgressBars(); } CDialogEx::OnTimer(nIDEvent); } void B2saomiaotuxiangchuangkou::OnLvnItemchangedListImages(NMHDR* pNMHDR, LRESULT* pResult) { LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR); int nItem = -1; if (pNMLV) { if ((pNMLV->uChanged & LVIF_STATE) && (pNMLV->uNewState & LVIS_SELECTED)) { nItem = pNMLV->iItem; } } else { nItem = 0; } if (!m_firstLoadCompleted && nItem == 0) { if (pResult) *pResult = 0; return; } if (nItem >= 0 && nItem < (int)m_imageFiles.size()) { CString filePath = m_imageFiles[nItem]; LoadImageToControl(filePath, IDC_STATIC_ORIGINAL_IMAGE); CWnd* pProcessed = GetDlgItem(IDC_STATIC_PROCESSED_IMAGE); if (pProcessed) { auto pStatic = reinterpret_cast<CStatic*>(pProcessed); HBITMAP hOldBmp = pStatic->GetBitmap(); if (hOldBmp) { DeleteObject(hOldBmp); pStatic->SetBitmap(NULL); } } } if (pResult) { *pResult = 0; } } void B2saomiaotuxiangchuangkou::ProcessImages() { for (m_currentIndex = 0; m_currentIndex < (int)m_imageFiles.size(); ++m_currentIndex) { if (m_stopped) break; while (m_paused && !m_stopped) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); } if (m_stopped) break; ProcessImage(m_imageFiles[m_currentIndex]); { std::lock_guard<std::mutex> lock(m_mutex); int totalProgress = static_cast<int>((static_cast<double>(m_currentIndex + 1) / m_imageFiles.size()) * 100); m_totalProgress.SetPos(totalProgress); m_fileProgress.SetPos(100); } std::this_thread::sleep_for(std::chrono::milliseconds(100)); } m_processing = false; m_stopped = true; PostMessage(WM_COMMAND, MAKEWPARAM(IDC_BUTTON_STOP, BN_CLICKED), (LPARAM)m_btnStop.m_hWnd); AfxMessageBox(_T("处理完成!")); } void B2saomiaotuxiangchuangkou::ProcessImage(const CString& filePath) { CT2CA filePathConverted(filePath); std::string filePathStr(filePathConverted); cv::Mat image = cv::imread(filePathStr); if (image.empty()) return; // 更新显示当前处理的图片 UpdateDisplayImage(filePath); cv::Mat processed; SimpleBinarization(image, processed); if (!processed.empty()) { CString tempPath = m_folderPath + _T("\\temp_processed.jpg"); SaveImage(processed, tempPath); LoadImageToControl(tempPath, IDC_STATIC_PROCESSED_IMAGE); DeleteFile(tempPath); } if (m_saveOption.GetCurSel() == 0) { SaveImage(processed, filePath); } else { CString fileName = GetFileNameFromPath(filePath); CString newPath = m_savePath + _T("\\") + fileName; SaveImage(processed, newPath); } for (int progress = 0; progress <= 100; progress += 10) { if (m_stopped) return; while (m_paused && !m_stopped) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); } if (m_stopped) return; { std::lock_guard<std::mutex> lock(m_mutex); m_fileProgress.SetPos(progress); } std::this_thread::sleep_for(std::chrono::milliseconds(50)); } } // 更新显示图片的函数 void B2saomiaotuxiangchuangkou::UpdateDisplayImage(const CString& filePath) { // 使用PostMessage安全地更新UI PostMessage(WM_UPDATE_DISPLAY_IMAGE, (WPARAM)(LPCTSTR)filePath, 0); } // 处理更新显示的消息 LRESULT B2saomiaotuxiangchuangkou::OnUpdateDisplayImage(WPARAM wParam, LPARAM lParam) { CString filePath = (LPCTSTR)wParam; if (filePath.IsEmpty()) return 0; std::lock_guard<std::mutex> lock(m_bitmapMutex); // 先释放之前的位图资源 if (m_currentBitmap) { DeleteObject(m_currentBitmap); m_currentBitmap = NULL; } // 加载新的位图 HBITMAP hBitmap = NULL; if (m_loadMode == MODE_OPENCV) { hBitmap = LoadImageWithOpenCV(filePath); } else { hBitmap = LoadImageWithGDIPlus(filePath); } if (hBitmap) { m_currentBitmap = hBitmap; CStatic* pStatic = dynamic_cast<CStatic*>(GetDlgItem(IDC_STATIC_ORIGINAL_IMAGE)); if (pStatic) { HBITMAP oldBmp = pStatic->GetBitmap(); if (oldBmp) DeleteObject(oldBmp); pStatic->SetBitmap(hBitmap); pStatic->Invalidate(); } } return 0; } void B2saomiaotuxiangchuangkou::SimpleBinarization(cv::Mat& input, cv::Mat& output) { cv::Mat gray; if (input.channels() == 3) { cv::cvtColor(input, gray, cv::COLOR_BGR2GRAY); } else { gray = input.clone(); } cv::threshold(gray, output, 128, 255, cv::THRESH_BINARY); } void B2saomiaotuxiangchuangkou::SaveImage(cv::Mat& img, const CString& filePath) { if (img.empty()) return; CT2CA filePathConverted(filePath); std::string filePathStr(filePathConverted); std::vector<int> compression_params; compression_params.push_back(cv::IMWRITE_JPEG_QUALITY); compression_params.push_back(95); cv::imwrite(filePathStr, img, compression_params); } void B2saomiaotuxiangchuangkou::UpdateProgressBars() { int totalProgress = static_cast<int>((static_cast<double>(m_currentIndex) / m_imageFiles.size() * 100)); m_totalProgress.SetPos(totalProgress); } void B2saomiaotuxiangchuangkou::CreateBackup() { if (m_folderPath.IsEmpty()) return; CTime time = CTime::GetCurrentTime(); CString timeStr = time.Format(_T("%Y%m%d%H%M%S")); m_backupPath = m_folderPath + _T("\\backup_") + timeStr; if (!CreateDirectory(m_backupPath, NULL)) { return; } for (const auto& file : m_imageFiles) { CString fileName = GetFileNameFromPath(file); CString destPath = m_backupPath + _T("\\") + fileName; CopyFile(file, destPath, FALSE); } } void B2saomiaotuxiangchuangkou::RestoreBackup() { if (m_backupPath.IsEmpty()) return; for (const auto& file : m_imageFiles) { CString fileName = GetFileNameFromPath(file); CString sourcePath = m_backupPath + _T("\\") + fileName; CopyFile(sourcePath, file, FALSE); } RemoveDirectory(m_backupPath); m_backupPath.Empty(); } void B2saomiaotuxiangchuangkou::Cleanup() { m_stopped = true; m_processing = false; if (m_processingThread.joinable()) { m_processingThread.join(); } KillTimer(1); // 释放位图资源 std::lock_guard<std::mutex> lock(m_bitmapMutex); if (m_currentBitmap) { DeleteObject(m_currentBitmap); m_currentBitmap = NULL; } HBITMAP hBmp = m_originalImage.GetBitmap(); if (hBmp) DeleteObject(hBmp); hBmp = m_processedImage.GetBitmap(); if (hBmp) DeleteObject(hBmp); } CString B2saomiaotuxiangchuangkou::GetFileNameFromPath(const CString& filePath) { int pos = filePath.ReverseFind('\\'); if (pos == -1) pos = filePath.ReverseFind('/'); if (pos != -1) { return filePath.Mid(pos + 1); } return filePath; } 该代码IDC_STATIC_ORIGINAL_IMAGE控件绘图时,绘制的图片相对于源图发生了水平偏移
最新发布
06-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值