Windows编程
毕业季的迷茫
IT小虾
展开
-
C++编写COM组件 ATL工程
最近在做QT项目中遇到一个问题,在Qt中调用MFC编写的动态库,出现内存泄露,没找到原因。由于这些库年代久远,内部代码也比较复杂,又不能轻易丢弃。于是我想把它们做成COM组件再试试。以下是一个简单COM组件编写和调用的完整流程,VS2015。1. 新建一个ATL项目工程建好后,会自动生成两个项目,只需要关注第一个就可以了。2. 添加自定义接口对象, MFCComObject ATL简单对象项目中添加了 CMFCComObject 类和 IMFCComObject ...原创 2022-03-26 12:52:49 · 2215 阅读 · 0 评论 -
OpenGL轨迹球
1. 在视图类里面创建以下变量class MyView{ ................ ArcBallT m_ArcBall; // 轨迹球, 记录轨迹的变化 Matrix4fT *m_pTransform; Matrix3fT *m_pLastRot; Matrix3fT *m_pThisRot; CPoint m_ptLast; // 记住鼠标上次鼠标的位置}MyView::MyView(){ ...原创 2021-11-09 22:14:55 · 562 阅读 · 0 评论 -
OpenGL表面剔除
渲染时,在特定的硬件上渲染的三角面片是有限的,那么这种情况下,就应该减少不必要的三角面片,提升性能。那么在进行面剔除时,我们如何知道哪些面属于前面的面(Front facing),哪些面是后面的面(Back facing),渲染时应该丢弃后面的面,来减少gpu在执行片断着色器的命令,OpenGL中通过判断顶点连接的顺序(Winding order)来解决这个问题。在我们使用OpenGL画一个三角形的时候,三个顶点一定有一个顺序,可能是顺时针也可能是逆时针,但是,我们是能够看到画出来的三角形的。原因是我们没原创 2021-11-09 22:13:04 · 321 阅读 · 0 评论 -
OpenGL光照设置
光照模型OpenGL光照模型分为三种光:Ambient Light 环境光, Diffuse Light漫反射光, Specular Light镜面反射光.一、创建光源void glLightfv (GLenum light, GLenum pname, const GLfloat *params)light: OpenGL提供8个光源 GL_LIGHT0 ~ GL_LIGHT7pname: 光源属性GL_AMBIENT 环境光 默认 (0.0, 0...原创 2021-11-09 22:12:23 · 5925 阅读 · 1 评论 -
OpenGL显示STL模型之光照设置
显示STL模型, 全部都是三角面片, 使用光照需要注意三角面片的法线, 法线的归一化尤为重要。模型经过glScale变换之后, 原来的法线变得不正确, 光照效果变得不理想。解决此问题的方法是启用OpenGL自动法线单位化功能,该功能会影响性能。glEnable( GL_NORMALIZE );较好的方法是提前将STL模型的法线单位化。另外需要注意的是, 观察位置gluLookAt常常要与光照一起设置。以下是经验使用方式:void SetLight(){ GLFloat box = s原创 2021-11-09 22:10:34 · 535 阅读 · 0 评论 -
OpenGL模拟地月星系运动
运动规则:-> 地球绕太阳公转, 公转半径为 R-> 月球绕地球公转, 公转半径为 r-> 太阳、地球、月球各自自转OpenGL模型变换原则, 对当前模型坐标系进行操作,无论是旋转、平移、缩放。可以想象成有很多模型坐标系,起初模型坐标系与世界坐标系重合。glRotated 当前坐标系(相对于世界坐标系)进行旋转glTranslated 当前坐标(相对于世界坐标系)进行平移glScale 当前坐标系(相对于世界坐标系)缩放doub...原创 2021-11-09 22:09:10 · 568 阅读 · 0 评论 -
3D视角旋转平移鼠标响应制作
OpenGL处理3D视角以及旋转变换的一个关键思路是归一化处理。归一化处理就是将数据进行单元化,将所有需要显示的数据等比例装在一个1X1X1的立方体里。然后OpenGL去显示这个立方体,设置视角gluLookAt eyex, eyey, eyez都以立方体的边长单位化。鼠标控制旋转的方法:->> 鼠标横向移动,控制图形绕着Y轴旋转;鼠标纵向移动,控制图形绕着X轴旋转;->> 鼠标一次移动消息中,只处理Y旋转或只处理X旋转;->> 鼠标滚轮控制图像绕着Z轴旋转原创 2021-11-09 22:08:06 · 269 阅读 · 0 评论 -
OpenGL真实坐标转换为投影后的坐标
真实坐标可以通过OpenGL的投影函数计算投影之后的坐标。在HLCut中用于处理鼠标点选操作。思路:获取OpenGL模型矩阵和投影矩阵,通过投影函数计算。函数: gluProjectdouble objx, objy, objz; // 保存着真实坐标GLint viewport[4];GLdouble mvmatrix[16], projmatrix[16];glGetIntegerv(GL_VIEWPORT, viewport);glGetDoublev(GL_MODELVIEW_M.原创 2021-11-09 22:06:51 · 411 阅读 · 0 评论 -
3D视图中获取鼠标所在位置
在3D视图中,经过旋转、缩放、平移之后,任然可以获取鼠标位置对应的真实坐标。思路:获取OpenGL模型矩阵和投影矩阵, 对鼠标位置信息进行反投影计算。主要函数:glReadPixels 通过深度缓存获取Z坐标gluUnProject 实现反投影POINT point; // 鼠标位置GLint viewport[4];GLdouble mvmatrix[16], projmatrix[16];glGetIntegerv(GL_VIEWPORT, viewport); // viewport.原创 2021-11-09 22:04:00 · 482 阅读 · 0 评论 -
MFC中使用OpenGL简单框架的搭建
#pragma onceclass COpenGLWnd : public CWnd{ DECLARE_DYNAMIC(COpenGLWnd)public: COpenGLWnd(); virtual ~COpenGLWnd(); int MySetPixelFormat(HDC hdc); void SetViewPortSize(); HDC m_hDC; HGLRC m_hRC;protected: DECLARE_MESSAGE_MAP()public: af.原创 2021-11-09 22:02:51 · 930 阅读 · 0 评论 -
C#封装动态库,提供给C++调用
1, 首先封装一个C# Dll, 即创建工程为C#类库;using System;using System.Collections.Generic;using System.Linq;using System.Runtime.InteropServices;using System.Text;using System.Threading.Tasks;namespace MyCharpDll{ [ComVisible(true)] [Guid("0CE96C54-CC5F-4...原创 2021-11-09 21:59:34 · 2233 阅读 · 1 评论 -
VC复制字符串到剪贴板
BOOL CopyToClipboard(HWND hWnd, CString& str){ if (!OpenClipboard(hWnd)) { AfxMessageBox(TEXT("Cannot open the Clipboard")); return FALSE; } if (!EmptyClipboard())//清空剪贴板 { AfxMessageBox(TEXT("Cannot empty the Clipboard")); return FALSE;.原创 2021-11-04 20:10:34 · 467 阅读 · 0 评论 -
CListCtrl图标与复选框使用
1. 首先类向导生成一个 CListCtrl 控件对象 m_listDO2. 添加CImageList对象,并与m_listDO绑定m_imgList.Create(16, 16, ILC_COLOR24, 2, 2);m_imgList.Add(AfxGetApp()->LoadIcon(IDI_OFF));m_imgList.Add(AfxGetApp()->LoadIcon(IDI_ON));m_listDO.SetImageList(&m_imgList, LVS原创 2021-11-04 20:08:59 · 505 阅读 · 0 评论 -
获取字符串的显示宽度和高度
1, 获取系统字符的宽度和高度 hdc = GetDC (hwnd) ; GetTextMetrics (hdc, &tm) ; cxChar = tm.tmAveCharWidth ; cyChar = tm.tmHeight + tm.tmExternalLeading ;2, 获取字符串的宽度和高度BOOL GetTextExtentPoint32( HDC hdc, // handle to DC LPCTSTR lpStri...原创 2021-07-07 15:50:18 · 615 阅读 · 0 评论 -
通过ToolHelp函数遍历系统所有进程
void GetTheProcess(){ //PROCESSENTRY32结构体,保存进程具体信息 PROCESSENTRY32 pe32; pe32.dwSize = sizeof(pe32); //获得系统进程快照的句柄 HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hProcessSnap == INVALID_HANDLE_VALUE) { return ; } //首.原创 2021-07-07 15:47:08 · 176 阅读 · 0 评论 -
CreateProcess打开EXE执行文件
STARTUPINFO si;PROCESS_INFORMATION pi;ZeroMemory(&si, sizeof(si));si.cb = sizeof(si);ZeroMemory(&pi, sizeof(pi));CreateProcess(NULL, "可执行文件EXE的路径名称", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);STARTUPINFO 可指定打开文件后如何显示,PROCESS_INFO..原创 2021-04-28 10:28:53 · 1001 阅读 · 0 评论 -
Win32多线程 -- 进程通讯
1. 进程通讯 WM_COPYDATA如果你尝试在进程A的线程中把一个 LPARAM (内含一个指针)交给进程B,进程B有可能在使用这一指针时当掉。问题出在这个指针所指的数据乃位于进程A的地址空间中。进程B不可能看到这个地址空间,所以这个指针会被以进程B的地址空间解释之。那当然是牛头不对马嘴了。为解决这个问题, Windows 定义了一个消息,名为 WM_COPYDATA ,专门用来在线程之间搬移数据--不管两个线程是否同属一个进程。和其他所有的消息一样,你必须指定一个窗口,也就是一个 HWND ,当原创 2021-03-31 23:52:03 · 271 阅读 · 0 评论 -
Win32多线程 -- MFC中的线程
警告如果要在 MFC 程序中产生一个线程, 而该线程将调用 MFC 函数或使用 MFC 的任何数据,那么你必须以 AfxBeginThread或CWinThread::CreateThread来产生这些线程。worker 线程和 GUI 线程Win32 两者一般而言都是以 CreateThread 或 _beginthreadex 开始其生命. 如果线程调用 GetMessage 或 CreateWindow 之类函数, 消息队列便会产生, 而 worker 线程也就摇身一变成了 GUI 线程(或称原创 2021-03-01 12:04:05 · 283 阅读 · 0 评论 -
stdio与Win32 Console API
stdio的格式化函数 sprintf, Win32对应地提供了 wsprinf, wsprintf 还细分为 _wsprintfA 和 _wsprintfW。stdio提供的三个标准流:stdin, stdout, stderr,Console API可以通过 GetStdHandle 获取到。HANDLE GetStdHandle( DWORD nStdHandle // STD_INPUT_HANDLE 对应 stdin // STD_OUT...原创 2021-03-01 11:57:50 · 101 阅读 · 0 评论 -
Win32多线程 -- C Run-time Librariy
Win32多线程程序建议:1. 以 _beginthreadex 取代 CreateThread2. 以 _endthreadex 取代 ExitThread3. 不要使用 _beginthread 和 _endthread4. 不要在MFC程序中使用 _beginthread 或 CreateThreadWindows区分单线程版本和多线程版本的 C Run-time Librariy , 多线程版本要使用 _beginthreadex 函数做初始化。如果任何线程中使用到了 C Run-ti.原创 2021-03-01 11:56:37 · 297 阅读 · 0 评论 -
Win32多线程 -- 异步IO(overlapped IO)
一. 异步(overlapped) IO之被激发的File Handle1.1Win32 IO操作函数Win32 之中有三个基本的函数用来执行 I/O CreateFile() ReadFile() WriteFile()没有另外哪一个函数用来关闭文件,只要调用 CloseHandle 即可。CreateFile 可以用来打开各式各样的资源,包括(但不限制于): -> 文件(硬盘、软盘、光盘或其他) -> 串行口和并行口(serial a...原创 2021-03-01 11:48:25 · 1270 阅读 · 0 评论 -
Win32多线程 -- 线程控制(暂停/继续/终止)
1. 关闭/终止 线程BOOL TerminateThread( HANDLE hThread, DWORD dwExitCode // 该线程的结束代码, GetExitCodeThread获取的值);如果函数成功, 则传回TRUE. 如果失败, 则传回FALSE. GetLastError()可以获知更多细节.2.暂停/挂起 线程DWORD SuspendThread( HANDLE hThread);如果函数成功, 传回线程目前的挂起次数. 如果失败...原创 2021-03-01 11:18:48 · 1493 阅读 · 0 评论 -
Win32多线程 -- 进程优先权与线程优先级
1. 优先权类别(Priority Class)"优先权类别"是进程的属性之一。这个属性可以表现出这一进程和其他进程比较之下的重要性。 Win32 提供四种优先权类别,每一个类别对应一个基本的优先权层级。下表展示了四个优先权类别。优先权类别(Priority Classes) 基础优先权值(base priority) HIGH_PRIORITY_CLASS 13 IDLE_PRIORITY_CLASS 4 NORMAL_PRIORITY_CLASS 7 or 8原创 2021-03-01 11:12:39 · 985 阅读 · 0 评论 -
Win32多线程 -- 同步机制摘要
1.Critical SectionCritical section(临界区)用来实现"排他性占有". 适用范围是单一进程的各线程之间. 它是: 一个局部性对象, 不是一个核心对象; 快速而有效率; 不能够同时有一个以上的critical section被等待; 无法侦测是否已被某个线程放弃;2.MutexMutex是一个核心对象, 可以在不同的线程之间实现"排他性占有", 甚至即使那些线程分属不同进程. 它是: 一个核心对象; 如果拥有mu...原创 2021-03-01 11:01:04 · 115 阅读 · 0 评论 -
Win32多线程 -- 线程同步之事件(Event)
Event对象被运用在多种类型的高级 I/O 操作中产生一个event对象HANDLE CreateEvent( LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, // FALSE, 表示这个event将在变成激发状态(因而唤醒一个线程)之后, 自动重置(reset)为非激发状态 // TRUE, 表示不会自动重置, 必须靠程序操作(调用ResetEvent())才能将激发状态的event重置为非激发状态 BOO原创 2021-03-01 10:57:05 · 366 阅读 · 0 评论 -
Win32多线程 -- 线程同步之信号量(Semaphores)
Semaphores是解决各种 producer/consumer问题的关键要素。这种问题会存有一个缓冲区,可能在同一时间内被读出数据或被写入数据。理论可以证明,mutex 是 semaphore 的一种退化。如果你产生一个semaphore 并令最大值为1,那就是一个 mutex。也因此, mutex又常被称为binary semaphore。在许多系统中, semaphores 常被使用, 因为 mutexes可能并不存在。在Win32中semaphores 被使用的情况就少得多,因为 mutex 存原创 2021-03-01 10:54:06 · 611 阅读 · 0 评论 -
Win32多线程 -- 线程同步之互斥器(Mutex)
CRITICAL_SECTION Mutex InitializeCriticalSection() CreateMutex() OpenMutex() EnterCriticalSection() WaitForSingleObject() WaitForMultipleObjects() MsgWaitForMultipleObjects() LeaveCriticalSection() ReleaseMutex() DeleteCriticalSec原创 2021-03-01 10:46:23 · 584 阅读 · 0 评论 -
Win32多线程 -- 线程同步之关键区域(临界区)与死锁
下面是链表结合CRITICAL_SECTION的例子(critical section不是内核对象): typedef struct _Node { struct _Node *next; int data; } Node; typedef struct _List { Node *head; CRITICAL_SECTION critical_sec; } List; List *CreateList() { List *pList = (List *)mall原创 2021-02-22 21:00:31 · 268 阅读 · 0 评论 -
Win32多线程 -- MTVERIFY宏
MTVERIFY 用以捕捉错误并协助找出其原因(针对返回值是BOOL的Win32API表达式)例如: MTVERIFY( CloseHandle(handle) );如果调用失败,输出信息格式如下:The following call failed at line 50 in Demo.c:CloseHandle(hThread)Reason: The handle is invalid#include <crtdbg.h> // 为了引入_ASSERTE#pragma co.原创 2021-02-22 20:53:22 · 140 阅读 · 0 评论 -
Win32多线程 -- 判断线程结束
相关函数1. GetExitCodeThreadBOOL GetExitCodeThread( HANDLE hThread, // handle to the thread LPDWORD lpExitCode // termination status);如果线程已经结束, lpExitCode 将会取得线程的返回值, 如果还未结束, lpExitCode的值是STILL_ACTIVE。这并不是好方法,因为线程的返回可能就是STILL_ACTIVE, 而这时线程已经结束。...原创 2021-02-22 20:51:58 · 885 阅读 · 0 评论 -
Win32多线程 -- 常见术语
原子操作一个操作(operation)如果能够不受中断地完成,我们称之为(原子操作)atomic operation.核心对象所谓handle,其实是个指针,指向操作系统内存空间中的某样东西,那东西不允许你直接取得。你的程序不能够直接取用它,为的是维护系统的完整性与安全性。Win32 核心对象的清单: 进程(processes) 线程(threads) 文件(files) 事件(events) 信号量(semaphores) 互斥器(mutexes)...原创 2021-02-22 20:38:29 · 119 阅读 · 0 评论 -
文件夹遍历实现
方法一#define _AFXDLL#include <afx.h>#include <iostream>using namespace std;// 文件夹和文件的查找使用 CFileFind类void BrowseDirectory(LPCTSTR strPath, int level){ CFileFind finder; BOOL bl; int i; // 把当前目录切换至制定的目录(不切换将会查找不成功) ::SetCurrentDire原创 2021-02-20 15:44:24 · 215 阅读 · 1 评论 -
CMFCPropertyGridCtrl项内容改变的响应
1, 设置列宽HDITEM hdItem;hdItem.cxy = 130; // 宽度为130 PixelhdItem.mask = HDI_WIDTH;m_wndGrid.GetHeaderCtrl().SetItem(0, new HDITEM(hdItem));2, 响应Item内容更改消息注册消息:ON_REGISTERED_MESSAGE(AFX_WM_PROPERTY_CHANGED, OnWndGridChanged)实现响应:LRESULT CDlgCCDAdjust.原创 2021-02-05 11:54:39 · 492 阅读 · 0 评论 -
CDockablePane嵌入MFCToolBar
// CToolPaneclass CToolPane : public CDockablePane{ DECLARE_DYNAMIC(CToolPane)public: CToolPane(); virtual ~CToolPane(); void AdjustLayout(); BOOL Create(CString strWndName, CWnd* pParentWnd, UINT nID, UINT uiResToolID, BOOL bVertical = FALSE, BOO.原创 2021-02-05 11:51:02 · 197 阅读 · 0 评论 -
CDockablePane中嵌入CFormView
// 从CDockablePane派生出CScrollPane class CScrollPane : public CDockablePane{ DECLARE_DYNAMIC(CScrollPane)public: CScrollPane(); virtual ~CScrollPane(); BOOL SetView(CRuntimeClass* pViewClass); CFormView* GetView() { return m_pView; }private: CFormV.原创 2021-02-05 11:49:48 · 237 阅读 · 0 评论 -
MFC对话框中实现菜单的更新
void CDlgMain::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu){ CDialogEx::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu); if (nIndex == 0) { if (!bSysMenu) { pPopupMenu->EnableMenuItem(ID_NEW_EDGE_CATCH, MF_GRAYED); pPopupM.原创 2021-02-05 11:47:41 · 284 阅读 · 0 评论 -
CFramWnd框架分屏实现
框架分屏1 在框架窗口类创建分屏成员变量CSplitterWnd m_splitter;2 重载OnCreateClient函数BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) { // TODO: Add your specialized code here and/or call the base class CRect rect; GetClientRect(&rec原创 2021-02-05 11:46:35 · 1042 阅读 · 1 评论 -
弹出路径选择对话框 SHBrowseForFolder
// 使用 BROWSEINFO 结构体,// SHBrowseForFolder 显示文件夹选择对话框// SHGetPathFromIDList 获得对话框选择的路径void CXXXDlg::OnSelectDirectory(){ TCHAR szPath[MAX_PATH]; memset(szPath, 0, sizeof(szPath)); BROWSEINFO bi; bi.hwndOwner = m_hWnd; // 拥有者窗体 bi.pidlRoot = NUL.原创 2021-02-05 11:42:49 · 543 阅读 · 0 评论 -
Windows HOOK
一、进程内HOOKHHOOK g_hKeyboard=NULL;BOOL CInnerHookDlg::OnInitDialog(){ ...// 安装HOOKg_hKeyboard=SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,NULL,GetCurrentThreadId()); ...}void CInnerHookDlg::OnClose(){ // 卸载HOOK UnhookWindowsHookEx(g_hKeyboard)原创 2021-01-12 09:59:18 · 248 阅读 · 0 评论 -
VC窗口鼠标停留与离开效果
需要响应三个消息ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)ON_WM_MOUSEMOVE()myWnd::m_bTracking = false;void myWnd::OnMouseMove(UINT nFlags, CPoint point){ if (!m_bTracking) //鼠标轨迹跟踪 { TRACKMOUSEEVENT tme; tme.cbS原创 2021-01-12 09:58:56 · 331 阅读 · 0 评论