45 天系列:CodeProject VC++ 论坛问答 - I
VC++论坛2004年12月10日至2005年1月23日期间的问答合集。
引言
没什么特别的…这篇文章是 compiled 的问题和答案,这些问题和答案是 2004年12月10日至2005年1月23日(45天)期间在 CodeProject Visual C++ 论坛 上提出的。另外,这也是45天系列的第一篇文章。希望我能在这个系列中带来更多内容。
感谢CodeProject论坛上为有需要的同行提供帮助的各位。我已经修改了一些原始评论以适应/维持文章的风格(对此我深表歉意)。如果我遗漏了什么,请随时发送邮件给我或在下方留言。
Content
[2004年12月10日至12月18日]
- 问题 1.01 有没有最小化窗口的函数?
- 问题 1.02 如何停止 SQL Server 登录对话框反复出现?
- 问题 1.03 如何访问 USB 端口 (COM 5)?
- 问题 1.04 窗口最大化或最小化时处理的是哪个窗口消息?
- 问题 1.05 每隔 40 毫秒运行一次计时器的最合适解决方案是什么?
- 问题 1.06 WM_GETTEXT 用于从编辑框检索文本的语法是什么?
- 问题 1.07 如何创建一个不是主窗口,但其父窗口和所有者窗口都为 NULL 的对话框,例如 MSN Messenger 中的聊天窗口?
- 问题 1.08 如何使用 Visual C++ 或 API 捕获 WEBCAM?
- 问题 1.09 C++ 中的 ^ 是做什么用的?
- 问题 1.10 如何在 C++ 中进行指数运算?如果 ^ 是 XOR…
- 问题 1.11 如何在 Windows 启动时运行一个 EXE 文件?
- 问题 1.12 关键字和保留字有什么区别?
- 问题 1.13 如何阻止对话框被调整大小和移动?
- 问题 1.14 如何编写应用程序的 .ini 文件?
- 问题 1.15 如何在运行时手动设置控件的 TAB 顺序?
- 问题 1.16 DEBUG_NEW 的功能是什么?
- 问题 1.17 DLL 和 LIB 文件有什么区别?
- 问题 1.18 给我一些确定应用程序完整路径的方法?
- 问题 1.19 什么是保护字节?
- 问题 1.20 如何调试正在运行的 DLL?
[2004年12月19日至12月27日]
- 问题 2.01 如何将调制解调器连接到电话?
- 问题 2.02 如何识别具有特定权限的用户(例如管理员权限等)?
- 问题 2.03 如何用一个具有结构作为参数的 C++ 项目调用 Web 服务?
- 问题 2.04 如何计算 RichEdit 控件中输入的字符总数?
- 问题 2.05 如何阻止 MFC 对话框应用程序显示在任务栏上?
- 问题 2.06 如何在 Windows 中设置显示分辨率?
- 问题 2.07 如何向窗口发送特定的按键?
- 问题 2.08 我需要某种方法来检查进程何时启动或退出。有什么想法吗?
- 问题 2.09 如何在对话框单位和像素之间进行转换以及反向转换?
- 问题 2.10 如何检查我正在使用的编译器版本?
- 问题 2.11 如何从 Win32 控制台应用程序在 XP 启动时将消息/文本输出到屏幕?
- 问题 2.12 如何在 MFC 规则 DLL 中使用 SetTimer()?
- 问题 2.13 有人知道如何通过 VC++ 将文件上传到 Web 服务器吗?
- 问题 2.14 如何在编辑控件内进行绘图?
[2004年12月28日至2005年1月5日]
- 问题 3.01 如何获取计算机的网络 IP 地址?
- 问题 3.02 如何消除调整窗口大小时的闪烁?
- 问题 3.03 如何查找哪个窗口属于哪个 exe 文件?
- 问题 3.04 有没有内置函数可以读取内存量或磁盘可用空间?
- 问题 3.05 如何打印/预览多页?
- 问题 3.06 关于“即时”刻录 CD 有什么建议吗?
- 问题 3.07 谁能给我一份虚拟键码列表?
- 问题 3.08 何时使用 extern "C"?这是编译器特定的功能吗?
- 问题 3.09 如何将网页链接写入“收藏夹”文件夹?
- 问题 3.10 有人能给我一个获取 MS Outlook 地址簿的代码示例吗?
- 问题 3.11 如何在运行时设置 MFC 对话框的窗口大小?
- 问题 3.12 如何使组合框不可编辑?
- 问题 3.13 如何以编程方式创建 DSN?
- 问题 3.14 如何动态显示和隐藏模态对话框的标题栏?
- 问题 3.15 您能提供一些制作全局热键的 MFC 资源(例如:源代码)吗?
- 问题 3.16 如何将图标添加到系统托盘?
- 问题 3.17 如何在 C++ 环境中使用 C 语言库?
- 问题 3.18 修改项目设置(按 Alt+F7)会修改哪个文件?
- 问题 3.19 如何检查一个文件是否已被任何进程打开?
- 问题 3.20 我的编译器将 WM_MOUSEWHEEL 指为“未声明的标识符”,问题是什么?
[2005年1月6日至1月14日]
- 问题 4.01 如何设置 CListCtrl 表头的字体?
- 问题 4.02 有人能给我 ZMODEM 的源代码参考吗?
- 问题 4.03 如何在 Visual C++ 中使用 Crystal Reports?
- 问题 4.04 是否有产生音频效果的软件或工具?
- 问题 4.05 如何检测用户点击了哪个 URL?
- 问题 4.06 为什么线程在类中使用时被声明为静态?
- 问题 4.07 Windows 在哪里存储拨号连接的日志?
- 问题 4.08 如何动态更改 UI(用户界面)的语言?
- 问题 4.09 关于原子钟和时区编程有什么建议吗?
- 问题 4.10 如何在线读取声卡数据?
- 问题 4.11 声明变量时 IN/OUT 是什么意思?
- 问题 4.12 如何获取特定文件夹的扇区位置?
[2005年1月15日至1月23日]
- 问题 5.01 如何更改编辑框的背景颜色?
- 问题 5.02 如何增加列表控件表头的高度?
- 问题 5.03 如何在网络/本地计算机上生成唯一密钥?
- 问题 5.04 如何获取文件的文件大小?
- 问题 5.05 有人知道数字相机的 API 吗?
- 问题 5.06 如何动态隐藏和显示菜单栏?
- 问题 5.07 请给我一个 RegEnumValue 的示例?
- 问题 5.08 如何禁用/启用属性表中的 OK 按钮?
- 问题 5.09 如何获取光盘 (CD) 的序列号?
- 问题 5.10 如何检查远程计算机是否存在?
- 问题 5.11 如何创建嵌套目录?
- 问题 5.12 如何获取对话框的 HWND?
- 问题 5.13 如何知道用户按住按钮的时间是否超过 250 毫秒?
答案
[2004年12月10日至12月18日]
问题 1.01 有没有最小化窗口的函数? [回到顶部^]
答:ThatsAlok 引用:
如果您使用的是 MFC:this->ShowWindow(SW_MINIMIZE);
如果您使用的是基于 Win32 API 的应用程序:ShowWindow(hWnd,SW_MINIMIZE);
问题 1.02 如何停止 SQL Server 登录对话框反复出现? [回到顶部^]
答:renjith_sree 引用:
在 OpenEx()
方法中使用 CDatabase::noOdbcDialog
作为第二个参数。例如:
extern CDatabase oDb; extern CString csConnection; oDb.OpenEx(csConnection, CDatabase::noOdbcDialog );
这将隐藏登录对话框。
问题 1.03 如何访问 USB 端口 (COM 5)? [回到顶部^]
答:Antti Keskinen 引用:
USB 是计算机内部的一个总线。低级驱动程序(由 Microsoft 提供)允许总线枚举和识别硬件,然后通过 USB 描述符返回的供应商和产品 ID 向注册表发送请求,以查找设备的正确功能驱动程序。这就是总线的工作原理。
您的计算机系统可能有一个仿真 COM 端口的伪设备驱动程序。加载此驱动程序时,它会打开一个到低级总线驱动程序的句柄,然后创建一个虚拟 COM 端口设备。之后,将 USB 数据包传入 COM 端口将直接路由到低级驱动程序,从而进入总线。不用说,错误的数据包可能会导致系统行为异常。这可能是您老板的意思。不过,您应该向他寻求澄清。
当此伪设备驱动程序未使用时,总线上的所有设备都由设备对象表示。对于每个具有可用且已加载的适当功能驱动程序的硬件设备对象,也存在一个驱动程序对象。此外,可能还存在筛选器驱动程序对象。您可以使用 WinObj 对象查看器(搜索它)来查看系统中当前存在的所有硬件设备对象、驱动程序对象和其他对象。相同的程序可用于获取驱动程序/设备对象的有效名称。如果您在内核模式下操作,可以使用此低级名称打开到驱动程序/设备的句柄。在用户模式下,由于 Windows NT/2000/XP 框架施加的安全限制,只能访问符号链接名称和有限的设备名称列表。
您可以通过 WinObj 查看所有这些。符号名称可以在“GLOBAL??”子树中找到。实际设备名称可以在“Device”子树中找到。作为参考,可以尝试查找一个普通的 COM 端口。您可以在那里找到它。“\Device\Serial0”对我来说是 COM1。
从这个列表(Global??)中,您可以通过查看供应商和产品 ID 来识别您的 USB 设备。为了大致了解您正在查看的是哪个设备的,您可以使用 Linux-USB 组的列表,该列表“有时”会定期更新。可以在 这里[^] 找到。所有 USB 设备都列为“USB#Vid_xxxx&Pid_xxxx&MI_xx#.....”。第一个是供应商 ID,下一个是产品 ID。最后一个我不确定。
请记住,一个设备在 WinObj 的“GLOBAL??”子树中可能有多个条目。我们感兴趣的是 \Device\USBPDO-X,它指的是 USB 总线上的物理设备对象。打开此设备的句柄允许您像读取/写入文件一样进行读取/写入。但是,可能会有安全限制。您也可以通过 WinObj 查看这些。如果您无法查看对象的属性,则说明您没有足够的权限。查看“安全性”选项卡,可以看到哪些用户拥有读取/写入/修改设备的权限。
例如,Logitech 的供应商 ID 是十六进制的 046d。我连接了 Logitech MX500 光学鼠标,其产品 ID 是十六进制的 c025。两者都来自 Linux-USB 列表。因此,在“GLOBAL??”中,我有一个条目“USB#Vid_046d&Pid_c025 etc”,它是“\DEVICE\USBPDO-5”的符号链接。这是我的 MX500 的物理设备对象。打开其属性,我可以看到在用户模式下,我只有“查询状态”权限,允许我请求有关设备的 status 信息。如果我以管理员身份登录,我还可以“删除”对象,这意味着设备已从总线逻辑断开。但是,总线会很快重新检测到设备,重新加载驱动程序并重新创建设备对象。
我无法在用户模式下从设备读取或写入。为此,我需要编写一个内核模式程序。该程序应创建一个虚拟设备,例如 USB MX500 鼠标,打开 USBPDO-5 的设备句柄,并将发送到虚拟设备的命令路由到物理设备并返回。我称之为粗糙的 hack,但它会达到目的。
问题 1.04 窗口最大化或最小化时处理的是哪个窗口消息? [回到顶部^]
答:prcarp 引用:
查看 WM_SIZE
wParam = SIZE_MAXIMIZED, SIZE_MINIMIZED, SIZE_RESTORED, etc.
lParam = cx -> lo word cy -> hi word
问题 1.05 每隔 40 毫秒运行一次计时器的最合适解决方案是什么? [回到顶部^]
答:John M. Drescher 引用:
问题在于时间切片比 1 毫秒大得多。请参阅这篇文章:时间是最简单的事情…
Antti Keskinen 引用:
Windows 不是时间关键型应用程序的最佳平台。但是,如果您必须使用它,可以尝试将应用程序的优先级提高到最高级别。这可以确保 40 毫秒(我假设是毫秒)计时器尽可能以 40 毫秒的间隔触发。
提高应用程序的优先级会导致其他应用程序失去优先级:提高应用程序的准确性可能会/将导致系统中并发执行的其他应用程序的不准确/僵硬响应/高延迟。将一个应用程序推向实时优先级很可能会导致当该单个应用程序运行时,操作系统看起来像是“死机”。但是,计时器将尽可能接近 40 毫秒的间隔。这就是您必须付出的代价。
在设计实时线程时,必须使其成为占用资源最少的进程。
例如,创建一个线程,提高其优先级,并使用指向要在 40 毫秒间隔运行的函数的指针调用 SetTimer
Win32 API 例程。然后将此线程放入一个可以中断的无限循环中(如果需要)。中断时,应终止计时器并终止线程。请注意,这不会导致系统死机,因为进程本身的优先级并未提高。您还可以使用 SetPriorityClass
来提升进程优先级。在执行此操作之前,请熟悉 MSDN 或 Visual Studio 文档中的 调度优先级[^]。误用线程或进程优先级很容易导致计算机死机。
要为您的 MFC 应用程序的主线程设置最高优先级,请使用 AfxGetApp()
获取 CWinApp
对象指针,并通过此指针调用 CWinThread::SetThreadPriority()
,并将参数设置为 THREAD_PRIORITY_TIME_CRITICAL
。CWinApp
派生自 CWinThread
。MFC 没有直接提升进程优先级的例程。您需要使用混合模式调用(CWinThread::operator HANDLE
和 SetPriorityClass
)来实现此目的。
在现代操作系统中,精确到 40 毫秒且没有微秒延迟或提前的计时器是不可能的。对于这样的目的,您需要设计和实现一个微控制器或类似的解决方案。
命名事件用于调度进程间操作或线程间操作。例如,您可以在远程线程中创建一个事件对象,以标记该线程已运行完一个循环。当事件对象被发出信号时,一个循环完成,下一个循环开始,如果这是一个连续系统。事件对象可以是全局的或局部的,具体取决于它们的创建方式。通常的规则是:全局用于进程间,局部用于线程间。
即使您使用命名事件,也需要某种方法来在 40 毫秒过去时将事件设置为已发出信号的状态。这又会将您带回计时问题和计时器。不过,命名事件是向其他线程或进程发出您的 40 毫秒间隔已过的最简单的方法。
问题 1.06 WM_GETTEXT 用于从编辑框检索文本的语法是什么? [回到顶部^]
答:Ravi Bhavnani 引用:
许多(实际上是大多数)操作窗口的 Windows API 调用是通过向目标窗口发送消息来实现的。WM_GETTEXT
是用于检索窗口文本的消息。这两个代码片段都可以获取编辑控件的文本
char szText [TEXTLEN]; HWND hWndEdit = window handle of edit control; ::GetWindowText (hWndEdit, szText, TEXTLEN - 1); char szText [TEXTLEN]; HWND hWndEdit = window handle of edit control; ::SendMessage (hWndEdit, WM_GETTEXT,(WPARAM) TEXTLEN - 1,(LPARAM) szText);
问题 1.07 如何创建一个不是主窗口,但其父窗口和所有者窗口都为 NULL 的对话框,例如 MSN Messenger 中的聊天窗口? [回到顶部^]
答:Mr.Prakash 引用:
通过调用 GetDeskTopWindow()
将每个对话框的父窗口设置为桌面窗口。
问题 1.08 如何使用 Visual C++ 或 API 捕获 WEBCAM? [回到顶部^]
答:Cyberizen 引用:
Microsoft Research 提供了一个名为“Vision SDK”的 SDK。使用此 SDK,您可以连接到您的摄像头并以各种格式捕获图像。我在 BS 第三年的项目中使用了这个 SDK。如果您需要任何额外的帮助,请告诉我。
附注:哦,我刚得知 Microsoft 将其 Vision SDK 产品卖给了一家德国公司,该公司可能使其商业化,因此可能不再公开提供。幸运的是,我找到了一个网站,您可以在其中 下载 Microsoft 版本。
Antti Keskinen 引用:
使用已安装的网络摄像头的最有效方法是使用 DirectShow,它随 DirectX 9 一起提供。
当安装并加载摄像头驱动程序时,它会为摄像头提供的视频流和图像创建一个 DirectShow 过滤器。此过滤器提供一个或多个接口,具体取决于摄像头提供的服务。如果您构建并操作一个“捕获链”(DirectShow 术语),您可以将来自摄像头的实时数据捕获到 Windows 窗口、文件或网络流中。
要在程序中使用 DirectShow,您必须下载并安装最新的 DirectX SDK,该 SDK 可从 Microsoft 免费获得。此 SDK 附带的 DirectX 文档中有一些关于如何创建捕获链的示例和代码片段。创建链的过程每次都类似:连接到链的过滤器决定链的性质、目的和功能。
例如,要使用网络摄像头将实时数据从摄像头传输到 Windows 窗口,请创建一个包含摄像头过滤器和视频渲染混合器过滤器的捕获链。VRM 过滤器可以将视频数据渲染到您创建并用 HWND
参数指定的窗口中。请记住,VRM 过滤器会创建一个辅助窗口,该窗口是您指定的 HWND
的子窗口。该辅助窗口没有标题栏、系统菜单等。它只是一个不断用视频数据重绘的空白方块。因此,您需要一个实际的顶层窗口来控制视频显示。您不能创建一个程序并在桌面上显示一个视频窗口,因为那样您将无法通过 CTRL+ALT+DEL 关闭程序。
问题 1.09 C++ 中的 ^ 是做什么用的? [回到顶部^]
答:toxcct 引用:
^ is the bitwise exclusive-or operator
SO : 0x1100 ^ 0x1010----------- = 0x0110
that's why number ^= 1; means number = number ^ 1;
means number = 0 ^ 1; // == 1
PJ Arends 引用:
请参阅:位运算符简介。
问题 1.10 如何在 C++ 中进行指数运算?如果 ^ 是 XOR… [回到顶部^]
答:Ryan Binns 引用:
使用 pow()
函数。
问题 1.11 如何在 Windows 启动时运行一个 EXE 文件? [回到顶部^]
答:goodmast3r 引用:
只需在 开始 > 程序 > 启动 中创建一个快捷方式。
Arsalan Malik 引用:
将您的 EXE 的路径(字符串值)添加到注册表中的以下位置:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run。
vishalmore 引用:
将您的 EXE 的路径添加到注册表中的以下位置:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run。
问题 1.12 关键字和保留字有什么区别? [回到顶部^]
答:Sujan Christo 引用:
请查看以下链接,它们可能对您有帮助:维基百科 - 关键字,保留字。
问题 1.13 如何阻止对话框被调整大小和移动? [回到顶部^]
答:Blake Miller 引用:
WM_GETMINMAXINFO
消息在窗口的大小或位置即将更改时发送给窗口。应用程序可以使用此消息来覆盖窗口的最大化大小和位置,或其默认的最小或最大跟踪大小。
如果将这两个大小都设置为相同,我非常确定您的窗口大小不会调整。您只需将最小和最大大小设置为相同。我没有测试过这种确切的行为,但这是我首先想到的想法。
问题 1.14 如何编写应用程序的 .ini 文件? [回到顶部^]
答:Greeeg 引用:
GetPrivateProfileXXX
和 WritePrivateProfileXXX
函数可以为您完成这项工作。
问题 1.15 如何在运行时手动设置控件的 TAB 顺序? [回到顶部^]
答:Ryan Binns 引用:
Tab 顺序就是窗口的 Z 顺序,所以要更改它,请使用 SetWindowPos()
问题 1.16 DEBUG_NEW 的功能是什么? [回到顶部^]
答:PJ Arends 引用:
它实现了调试器能够跟踪内存泄漏分配位置的行号和文件名。
问题 1.17 DLL 和 LIB 文件有什么区别? [回到顶部^]
答:John R. Shaw 引用:
过去,如果您链接了一个普通的 .LIB 文件,那么您就链接了该文件中包含的所有函数,无论您是否使用它们。我不知道现在是否仍然如此,但这导致程序比实际工作所需的要大得多,因为链接的大部分函数都没有被使用。再加上每个程序都有其自身的相同函数代码版本。
如果多个程序使用同一个库中的相同函数,那么您应该使用 DLL。这样,所有程序都可以共享相同的代码:这会减小各个程序的大小,并减少存储这些程序及其依赖库所需的磁盘空间。它还减少了加载程序所需的内存量。
问题 1.18 给我一些确定应用程序完整路径的方法? [回到顶部^]
答:Antony M Kancidrowski 引用:
这是一个可以完成这项工作的函数。是的,我知道它是全局的,但您可以将其内容提取出来并包装成类函数!
inline CString GetModuleLoadPath() // Returns the load path of the module (ends in '\') { int Idx; TCHAR ModName[_MAX_PATH]; if(!::GetModuleFileName(NULL,ModName,sizeof(ModName)) ) { ASSERT(false); return CString(_T("")); } CString LoadPath(ModName); Idx = LoadPath.ReverseFind(_T('\\')); if( Idx == -1 ) { ASSERT(false); return CString(_T("")); } LoadPath = LoadPath.Mid(0,Idx+1); return LoadPath; }
问题 1.19 什么是保护字节? [回到顶部^]
答:peterchen 引用:
malloc_dbg
调用 malloc
,但请求额外的几个字节。这些字节用预定义值填充。然后 free_dbg
检查这些额外字节是否仍然保持此值。如果它们仍然保持该值,则您可能写越过了分配的内存(VC Runtime 会在调试输出中打印一条诊断消息)。典型的实现是在末尾添加 4 个字节。
在这种情况下,使用 free
而不是 _free_dbg
通常没问题,但根据实现,它可能会泄漏保护字节。但是,如果实现 *在* 提供给您的内存 *之前* 添加了保护字节(以检测不常见的下溢),则使用 free
而不是 -free_dbg
可能会损坏堆。
问题 1.20 如何调试正在运行的 DLL? [回到顶部^]
答:avenger_sb25 引用:
好吧,如果您使用的是 Visual Studio IDE,请按 F9 在源文件中设置断点。然后,转到:项目>>设置>>调试选项卡。在“调试会话的可执行文件:”编辑框中,浏览并选择将使用您的 DLL 的 EXE 文件。然后按“确定”。
现在,通过单击工具栏上的“!”图标或运行您的程序。这将运行您之前选择的 EXE。现在,如果该程序(EXE)使用了您 DLL 中的导出函数,并且您已正确设置了断点,您就可以调试您的 DLL 了……
renjith_sree 引用:
在项目 > 设置 > 调试(调试的可执行文件部分)中放入 EXE 文件名。
[2004年12月19日至12月27日]
问题 2.01 如何将调制解调器连接到电话? [回到顶部^]
答:Antti Keskinen 引用:
您应该使用 TAPI(电话 API)而不是 Win32 的 CreateFile
。请参阅 Visual Studio 文档或 MSDN 以获取参考和示例。TAPI 随 Platform SDK 一起安装,因此它捆绑在大多数 Visual Studio 发行版中,并且/或者您也可以从 Internet 下载它。
TAPI 有一对名为 lineGenerateDigits
和 lineGatherDigits
的函数,它们生成和收集代表数字的脉冲序列。您还可以使用 lineGenerateTone
和 lineMonitorTone
发送和监控单个脉冲。
这些函数仅存在于 TAPI 版本 2.x 中。在版本 3.x 中,引入了 COM 模型,并且电话线上的所有运行内容都被视为流,终端对象充当接收器。对您来说,我建议使用 TAPI 2.x(如果可能)。COM 模型对于您所需的功能来说过于复杂。
问题 2.02 如何识别具有特定权限的用户? (例如管理员权限等) [回到顶部^]
答:DavidCrow 引用:
NetUserGetInfo()
能满足您的要求吗?
问题 2.03 如何用一个具有结构作为参数的 C++ 项目调用 Web 服务? 回到顶部[^]
答:Antti Keskinen 引用:
您使用的是 Visual Studio 6.0 吗?如果是,请考虑升级到 Visual Studio .NET 2003。它具有出色的“添加 Web 引用”向导,该向导会为 Web 服务生成包装类。这意味着,如果 Web 服务的 WSDL 定义它接受一个数组,那么类的调用方法也需要一个数组。如果您无法升级环境,请尝试从 Microsoft 获取最新的 SOAP Toolkit 并进行安装。其支持将于 2005 年 4 月停止,但仍可下载。
SOAP Toolkit 被弃用的主要原因是 .NET Framework 的出现,它本身就支持 Web 服务。不过,使用 .NET 需要 Visual Studio .NET 2002 或更高版本,所以您又面临同样的问题。SOAP Toolkit 指定了 COM 对象 SoapClient30
。该 COM 对象可以根据 WSDL 文件自行初始化。话虽如此,获取您想使用的 Web 服务的 WSDL 文件,使用 COM 创建 SoapClient30
对象,使用 WSDL 文件初始化它,然后您就可以直接调用接受数组作为参数的方法了。
问题 2.04 如何计算 RichEdit 控件中输入的字符总数? [回到顶部^]
答:DavidCrow 引用:
GetWindowTextLength()
怎么样?
问题 2.05 如何阻止 MFC 对话框应用程序显示在任务栏上? [回到顶部^]
答:Mohammad A Gdeisat 引用:
我引用 MSDN 2003 的以下内容,我不知道它是否真的有效,但我希望如此:我只会告诉你答案:你必须将你的对话框创建为不可见窗口的子窗口,该窗口具有 WS_EX_TOOLWINDOW
样式,并且你必须确保你的对话框具有 WS_EX_APPWINDOW
样式。如果你仔细阅读文档,你可能会弄清楚这一点——但只有当你使用强大的放大镜时。
// pre-create window: set WS_EX_TOOLWINDOW style // BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) { if (CFrameWnd::PreCreateWindow(cs)) { cs.dwExStyle |= WS_EX_TOOLWINDOW; return TRUE; } return FALSE; } // InitInstance: create dialog as child of invisible main frame // BOOL CMyApp::InitInstance() { CMainFrame* pFrame = new CMainFrame; m_pMainWnd = pFrame; pFrame->LoadFrame(IDR_MAINFRAME,WS_OVERLAPPED, NULL, NULL); CMyDlg dlg(pFrame); int nResponse = dlg.DoModal(); if (nResponse == IDOK) { } else if (nResponse == IDCANCEL) { } return FALSE; }
问题 2.06 如何设置 Windows 中的显示分辨率? [回到顶部^]
答:DavidCrow 引用:
ChangeDisplaySettings()
怎么样?
问题 2.07 如何向窗口发送特定的按键? [回到顶部^]
答:Antti Keskinen 引用:
当窗口获得焦点且非系统键盘键按下并保持按下状态时,会向窗口发送 WM_KEYDOWN
消息。键盘重复延迟后,会同时生成多个 WM_KEYDOWN
消息。非系统键盘键是指除 F10 键以及与 ALT 键一起按下的键之外的任何键。要模拟 ALT + 键组合,请使用 WM_SYSKEYDOWN
消息。
为了模拟向窗口按键,请使用 WM_CHAR
消息。WM_CHAR
消息不再进行转换,因此您为其发出的键码将直接原样发送到接收窗口。WM_KEYDOWN
消息具有虚拟键码,这些键码会被转换为字符码。WM_CHAR
消息附带字符码(ASCII)值。
要精确模拟按键(如 CTRL/SHIFT + 键),您必须生成虚拟按键事件。这比仅仅发送单个消息要复杂得多。请在 MSDN 中查看 SendInput
。在这里,您将为组合键的每个事件生成连续的键盘事件。请记住,例如,按下 CTRL + SHIFT + F 由按顺序按下 CTRL、SHIFT 和 F 键,然后按相反顺序释放它们组成。请注意,要定位按键组合,您必须通过使用 SetFocus
将目标窗口设置为活动窗口。
此外,如果您的程序运行在与目标程序不同的线程中,您必须首先使用 AttachThreadInput
附加输入流,并在合成击键后分离它们。
问题 2.08 我需要某种方法来检查进程何时启动或退出。有什么想法吗? [回到顶部^]
答:ThatsAlok 引用:
您必须在进程上设置一个系统范围的 Hook,类型为 WH_CBT
,并监听 WM_QUIT
、WM_CREATE
消息。SetWindowHookEx
将是这种情况下的 API 使用!
问题 2.09 如何在对话框单位和像素之间进行转换以及反向转换? [回到顶部^]
答:DavidCrow 引用:
这是一个非常糟糕的主意。对话框单位的使用是有原因的,那就是程序不必关心当前使用的分辨率和字体。通过硬编码基于像素大小的控件,您将程序的便携性仅限于一台计算机。有关更多信息,请参阅 此评论。
Michael Dunn 引用:
使用 MapDialogRect()
进行转换。
问题 2.10 如何检查我正在使用的编译器版本? [回到顶部^]
答:Michael Dunn 引用:
测试 _MSC_VER
符号。对于 VC 7,它是 1300;对于 VC 7.1,它是 1310;对于带有编译器版本 12.00 的 VC 6,_MSC_VER
是 1200。
问题 2.11 如何从 Win32 控制台应用程序在 XP 启动时将消息/文本输出到屏幕? [回到顶部^]
答:Michael Dunn 引用:
这是一个开始:HKLM\SYSTEM\CurrentControlSet\Control\Session Manager,字符串值 BootExecute
包含要运行的命令行。
WoutL 引用:
e-sushi 引用:
我好像找到了一些更有用的东西… Windows 驱动程序构建方法和工具。
问题 2.12 如何在 MFC 规则 DLL 中使用 SetTimer()? [回到顶部^]
答:Ravi Bhavnani 引用:
SetTimer()
是 CWnd
类的一个方法。您使用该函数会调用全局作用域的 ::SetTimer()
Windows API 调用,该调用将窗口句柄作为第一个参数。传递“1000”很可能会导致异常行为。
您应该将有效的 CWnd
(或窗口句柄)传递给您的 DLLClass
对象,该对象可以传递给 Test()
中的 SetTimer()
调用。
问题 2.13 有人知道如何通过 VC++ 将文件上传到 Web 服务器吗? [回到顶部^]
答:Neville Franks 引用:
请查看:InternetWriteFile()
。
我假设您需要权限/身份验证才能执行此操作。使用 FTP 可能会更好。
问题 2.14 如何在编辑控件内进行绘图? [回到顶部^]
答:DELIVER THE PROMISE 引用:
- 您可以从
CEdit
派生一个类并处理OnPaint()
。您将在那里有一个 DC。您可以使用它进行绘图,例如:dc.MoveTo() - dc.LineTo()
。 - 或者您可以调用:
CDC* pDC = CEdit.GetDC(); pDC->MoveTo(), pDC->LineTo()
。
[2004年12月28日至2005年1月5日]
问题 3.01 如何获取计算机的网络 IP 地址? [回到顶部^]
答:DavidCrow 引用:
要获取计算机的 IP 地址,请使用 gethostbyname()
。
问题 3.02 如何消除调整窗口大小时的闪烁? [回到顶部^]
答:SteveKing 引用:
尝试修改 CWnd::OnEraseBkgnd(..)
,它会擦除背景。
问题 3.03 如何查找哪个窗口属于哪个 EXE 文件? [回到顶部^]
答:Gary R. Wheeler 引用:
为什么不使用正确的功能:GetWindowModuleFileName()
。
有没有内置函数可以读取内存量或磁盘可用空间? [回到顶部^]
答:Michael Dunn 引用:
C++ 没有内置这样的函数,因为这种信息本质上是平台特定的。可以查看 GlobalMemoryStatus()
和 GetDiskFreeSpaceEx()
API。
问题 3.05 如何打印/预览多页? [回到顶部^]
答:PJ Arends 引用:
关于“即时”刻录 CD 有什么建议吗? [回到顶部^]
答:Henry miller 引用:
首先,如果您有选择,请使用 DVD+R 或 DVD+RW,因为它们对防止“欠载”的支持最好。实际上,如果您使用的是 CD,为了合法,您必须确保您的数据流足够大,以便在驱动器准备好时(即使您不准备好!)写入数据!我一直在现代驱动器上违反此规则,没有太多问题,但如果您要销售此产品,则需要要求您的客户拥有具有良好欠载保护的驱动器。
接下来,转到 www.t10.org 并购买 MMC 标准(您也可以下载它们,但不是最新版本…)。您可能需要考虑加入,具体取决于您的技术人员。t10 是 SCSI 标准组织。所有速度超过 4x 的 CD 刻录机都是 SCSI 的!(它可能是电路上为 IDE 或 USB,但它会说 SCSI 标准,所以这是您关心的。)阅读标准几次,直到您认为自己理解了它。
现在,弄清楚如何在您的操作系统上发送 SCSI 命令。在 Windows NT/2000/XP 上,它是 device_ioctl
SCSI_PASSTHROUGH_DIRECT
(或类似名称)。Windows 95/98/ME 使用其他方式。UNIX 则不同,每个 UNIX 都不同。
接下来您需要确定您将使用什么标准来写入数据。我对 VCD 标准一无所知,所以帮不了您。如果您不关心其他任何人是否能读取磁盘,您可以定义自己的格式。
如果您想写入文件,那么您可以研究 UDF(我没有,但这可能是正确的方法),或者您可以写入 ISO-9660。ISO-9660 最容易在 ECMA-119 名称下找到。获取规范,并将其了如指掌。您只需要知道一个细节:在磁盘开始处预留一个磁道,然后在下一个磁道写入数据,完成后将目录写入预留的磁道。
我花了大约 4 个月的时间才自己编写了此代码(从设计到发布)。我有一个现成的 SCSI 抽象层,所以我不需要担心许多您将需要学习的细节。一旦您理解了标准并有了设计,代码就只需要几周时间,但需要一段时间才能弄清楚如何阅读所有标准。
问题 3.07 谁能给我一份虚拟键码列表? [回到顶部^]
答:Heath Stewart 引用:
诸如此类的常量定义在随 VC++ 一起安装的头文件中。如果您找到,例如 VK_UP
,那么您就可以看到所有其他常量。它们定义在 winuser.h 中,并在 MSDN 中有文档。
问题 3.08 何时使用 extern "C"?这是编译器特定的功能吗? [回到顶部^]
答:Lim Bio Liong 引用:
extern "C"
声明用于告知 C++ 编译器不要进行符号名修饰(mangling)。
当 C++ 编译器遇到一个未声明为 extern "C"
的函数名(如“DisplayCurrentThreadId()
”)时,它会为其生成一个符号,该符号看起来如下:
?DisplayCurrentThreadId@@YAXXZ
实际生成的符号取决于所使用的编译器(上面是由 VC++ 6.0 生成的)。该符号将在生成的 OBJ 文件中用于链接。
C++ 对符号名修饰有多种原因,当然。但函数名修饰(包括类函数和全局函数)的原因是为了支持函数名重载(即使用相同的函数名和不同的参数类型)。
如果 extern "C"
用于声明函数,那么生成的符号可能是
_DisplayCurrentThreadId
这取决于所使用的编译器。但底线是,不允许函数名重载(因为 C 语言不支持这一点,因此 extern "C"
)。
问题 3.09 如何将网页链接写入“收藏夹”文件夹? [回到顶部^]
答:Michael Dunn 引用:
请参阅 MSDN。
问题 3.10 有人能给我一个获取 MS Outlook 地址簿的代码示例吗? [回到顶部^]
答:Ravi Bhavnani 引用:
也许 这篇文章[^] 会有所帮助?
问题 3.11 如何在运行时设置 MFC 对话框的窗口大小? [回到顶部^]
答:Ravi Bhavnani 引用:
请参阅 SetWindowPos()
和 MoveWindow()
。
问题 3.12 如何使组合框不可编辑? [回到顶部^]
答:cedric moonen 引用:
进入组合框的属性 -> “样式”选项卡,然后在“类型”组合框中选择“DropList”。
问题 3.13 如何以编程方式创建 DSN?[回到顶部^]
答:DavidCrow 引用:
使用 SQLConfigDataSource()
。
问题 3.14 如何动态显示和隐藏模态对话框的标题栏? [回到顶部^]
答:k_dehairy 引用:
尝试使用对话框的此成员函数
//this will hide the title ModifyStyle(WS_CAPTION,0); //then call SetWindowPos()with cx and cy of your own ::SetWindowPos(m_hWnd,HWND_TOP,0,0,cx,cy,SWP_SHOWWINDOW);
要恢复工具栏
//this will show the title ModifyStyle(0,WS_CAPTION); ::SetWindowPos(m_hWnd,HWND_TOP,0,0,cx,cy,SWP_SHOWWINDOW);
问题 3.15 您能提供一些制作全局热键的 MFC 资源(例如:源代码)吗? [回到顶部^]
答:ThatsAlok 引用:
问题 3.16 如何将图标添加到系统托盘? [回到顶部^]
答:Michael P Butler 引用:
ThatsAlok 引用:
再加一个
问题 3.17 如何在 C++ 环境中使用 C 语言库? [回到顶部^]
答:Michael Dunn 引用:
在您的 C++ 代码中,这样做:
extern "C" { #include "your_c_header.h" }
问题 3.18 修改项目设置(按 Alt+F7)会修改哪个文件? [回到顶部^]
答:ThatsAlok 引用:
当您按 Alt+F7 时,您的 Project.DSP 将被修改。
问题 3.19 如何检查一个文件是否已被任何进程打开? [回到顶部^]
答:Rajesh match 引用:
查看 MSDN 中的 CFile::shareExclusive
。
cmk 引用:
问题 3.20 我的编译器将 WM_MOUSEWHEEL 指为“未声明的标识符”,问题是什么? [回到顶部^]
答:PJ Arends 引用:
来自 WinUser.h
#if (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400) #define WM_MOUSEWHEEL 0x020A #endif
注意 #if
?确保 _WIN32_WINNT
或 _WIN32_WINDOWS
已正确定义。
[2005年1月6日至1月14日]
问题 4.01 如何设置 CListCtrl 表头的字体? [回到顶部^]
答:basementman 引用:
//CFont Varible CFont m_fArial; //Create Arial Font m_fArial.CreateFont(14,0,0,0,FW_BOLD,FALSE,FALSE,FALSE, DEFAULT_CHARSET,OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH,"Arial"); //Get Pointer of ListCtrl CListCtrl *m_pList = (CListCtrl*)GetDlgItem(IDC_LIST1); //Set Font if (m_pList) m_pList->GetHeaderCtrl()->SetFont(&m_fArial);
这里的关键是获取指向 CListCtrl
的嵌入式 Header 控件的指针。
问题 4.02 有人能给我 ZMODEM 的源代码参考吗? [回到顶部^]
答:Ravi Bhavnani 引用:
您可以尝试移植这个 Unix 示例[^]。这里也有一些源代码 在这里[^]。另请参阅此 商业源代码[^]。
问题 4.03 如何在 Visual C++ 中使用 Crystal Reports? [回到顶部^]
答:Michael P Butler 引用:
请查看此 示例列表[^]。
问题 4.04 是否有产生音频效果的软件或工具? [回到顶部^]
答:Marcus Spitzmiller 引用:
上次我检查时,DirectX 在其 DirectSound 组件中完成了所有这些工作:您可以在 这里 研究或下载 SDK。
Ravi Bhavnani 引用:
我使用 Bass[^]。
问题 4.05 如何检测用户点击了哪个 URL? [回到顶部^]
答:Michael Dunn 引用:
OnBeforeNavigate2
事件会将即将导航到的 URL 传递给您。
Antti Keskinen 引用:
与其使用 IWebBrowser2
,不如使用标准的 COM 方法,并注册以接收来自 DWebBrowserEvents
接口的通知。首先查询 IConnectionPointContainer
接口。然后请求 DWebBrowserEvents
的 IConnectionPoint
接口。然后使用 IConnectionPoint::Advise
注册您的类。
您使用的类必须派生自 DWebBrowserEvents
并且必须实现其所有方法。未使用的事件应返回 S_OK
。您感兴趣的事件是 DWebBrowserEvents::NavigateComplete
。此事件将包含客户端被重定向到的最终 URL。
问题 4.06 为什么线程在类中使用时被声明为静态? [回到顶部^]
答:Toby Opferman 引用:
当与 C++ 类一起使用时,用于创建线程的函数被定义为“静态”,因为有一个隐含的参数在代码中不显示,即 THIS
指针。
为了避免这种混淆并使其简单化,“静态”类成员仅操作静态数据,而不是每个实例的数据,因此不传递“this
”指针。因此,很容易将函数定义为静态并在 CreateThread
中使用它而无需担心。当然,它们通常会将对象实例作为第一个参数传递。
class x { public: static DWORD WINAPI MyThread(PVOID lParam) { x *pX = (x *)lParam; // Happy Happy Joy Joy } }................ x pX = new x; CreateThread(...., x::MyThread, pX);
正如上面的例子所示,可以创建线程,系统会传递“this
”指针,然后我们手动重用它。
在 C++ 中执行此操作的另一种方法是简单地将类函数定义为标准调用,**而不是快速调用**,并接受“void
”参数。
class x { public: DWORD WINAPI MyThread(void); }; ... x *pX = new x; CreateThread(..., x::MyThread, pX);
为什么是 void
参数?
因为系统现在会为您传递“this
”指针,而在 C++ 中,语言会隐藏这个细节。
为什么是 stdcall 而不是 fastcall?
STDCALL 应该通过堆栈传递“this
”指针,而 fastcall 将 this
指针传递到 ECX
寄存器中,系统对此一无所知。
问题 4.07 Windows 在哪里存储拨号连接的日志? [回到顶部^]
答:Michael Dunn 引用:
查看您的系统事件日志,当连接建立或断开时,您会看到来自 RemoteAccess
服务的条目。
问题 4.08 如何动态更改 UI(用户界面)的语言? [回到顶部^]
答:Maximilien 引用:
最好的方法是使用多个资源文件,每个语言使用一个。每个资源将位于 DLL 中,并在应用程序启动时(或用户选择菜单项后)加载。
看看
问题 4.09 关于原子钟和时区编程有什么建议吗? [回到顶部^]
答:Mike Dimmick 引用:
现代 Windows 版本(XP、2003)预配置为使用 简单网络时间协议 (SNTP)[^] 联系 time.windows.com。如果您将机器加入 2000 或 2003 Active Directory 域,则该机器会从域控制器获取时间。
其次,我也需要显示其他时区的时间,比如我在洛杉矶,想显示伦敦和纽约的时间。有人有关于如何确定其他时区、区域时间的信息链接吗?
我的世界时钟[^] 示例应用程序可以做到这一点。源代码在此链接处可用 - 这是一个 C# 应用程序,但它使用操作系统函数调用进行实际的时间转换。棘手的部分是处理夏令时 - 否则它将是一个简单的偏移量计算。
我最大的问题是如何让用户选择他们的位置,以及软件如何知道该位置的时区等?
您必须拥有某种位置数据库以及相应时区的信息。
问题 4.10 如何在线读取声卡数据? [回到顶部^]
答:K(arl) 引用:
您可以使用波形音频接口记录这些数据。您可以在 MSDN 上找到关于如何使用此 API 记录音频数据的说明。
问题 4.11 声明变量时 IN/OUT 是什么意思? [回到顶部^]
答:DavidCrow 引用:
基本上,它指示变量何时包含有效信息。IN
表示在调用函数时变量包含有效信息;OUT
表示在调用函数返回后变量将包含有效信息。请参阅“按引用传递”和“按值传递”以获取相关信息。
问题 4.12 如何获取特定文件夹的扇区位置? [回到顶部^]
答:匿名引用:
您可以使用 ASPI 或 SPTI 读取 CD 扇区。扫描 TOC 以定位特定的文件夹描述符(参见 ISO 9660)。要发送 ASPI 命令,您可以使用 winaspi.dll 中的“SendASPI32Command
”函数,或使用 DeviceIOControl
发送 SPTI 命令。
[2005年1月15日至1月23日]
问题 5.01 如何更改编辑框的背景颜色? [回到顶部^]
答:Gary R. Wheeler 引用:
您可以通过处理对话框中的 WM_CTLCOLOR
消息来更改对话框中编辑控件的背景颜色。
class MyDialog : public CDialog { //... COLORREF _BkgColor; HBRUSH _BkgBrush; }; BOOL MyDialog::OnInitDialog() { //... _BkgColor = RGB(0,255,0); _BkgBrush = ::CreateSolidBrush(_BkgColor); } HBRUSH MyDialog::OnCtlColor( CDC* pDC, CWnd* pWnd, UINT nCtlColor ) { hbr = CDialog::OnCtlColor(pDC,pWnd,nCtlColor); if (pWnd()->GetDlgCtrlId() == IDC_MY_EDIT_CONTROL) { pDC->SetBkColor(_BkgColor); hbr = _BkgBrush; } return hbr; }
在对话框的 OnInitDialog()
处理程序中,我们初始化背景颜色值并创建该颜色的画笔。WM_CTLCOLOR
处理程序被调用为 OnCtlColor
。我们要更改颜色的编辑控件的资源 ID 为 IDC_MY_EDIT_CONTROL
。我们使用 SetBkColor()
将文本背景设置为我们的背景颜色,并通过返回我们创建的画笔来设置控件的整体背景。
问题 5.02 如何增加列表控件表头的高度? [回到顶部^]
答:Martin Koorts 引用:
我查看了一下,发现没有办法——从 CListCtrl
检索到的 CHeaderCtrl
只有调整列宽的功能。您必须查看所有者绘图。
问题 5.03 如何在网络/本地计算机上生成唯一密钥? [回到顶部^]
答:Martin Koorts 引用:
这里的“模式”是选择是:
- 由中央机构生成唯一 ID(相对于自身)- 例如,在数据库表中具有自动增量 ID,或类似内容 -
还是…
- 生成绝对唯一 ID(使用
UuidCreate
/UuidCreatSequential
)- 可以在任何地方创建,无需联系权威机构。
在分布式环境中,选项 a) 不仅引入了一个瓶颈(考虑许多客户端同时请求 ID 或 ID 范围),而且在性能方面也无法与客户端本地 GUID 生成相比(网络时间通常无法与本地 CPU/硬件时间相比)。
除非 GUID 生成引起技术障碍,或者您需要具有可预测值的 ID,否则我建议您使用它。
此外,您可能希望将其设计成您现在可以开始使用 GUID,并在您的实现中利用这个已知、经过验证的功能;稍后,如果您仍然觉得 ID 的性能或大小太大,可以在不影响设计的情况下将其更改为自定义的。换句话说,ID 是不透明的且大小可变。
问题 5.04 如何获取文件的文件大小? [回到顶部^]
答:DavidCrow 引用:
好的,有什么问题吗?
DWORD SizeOfFile( LPCTSTR lpszFile ) { DWORD dwSize = 0; HANDLE hFile; hFile = CreateFile(lpszFile, 0, 0, NULL, OPEN_EXISTING, ...); if (hFile != INVALID_HANDLE_VALUE) { dwSize = GetFileSize(hFile, NULL); // you may want to use GetFileSizeEx() instead CloseHandle(hFile); } return (dwSize); }
showe 引用:
试试
CFile myFile(lpszFileName, CFile::modeRead); int len = myFile.GetLength();
问题 5.05 有人知道数字相机的 API 吗? [回到顶部^]
答:Mike Dimmick 引用:
问题 5.06 如何动态隐藏和显示菜单栏? [回到顶部^]
答:Serge Krynine 引用:
我认为这段代码能说明您需要什么
void CShowHideMenuDlg::OnShowMenu() { // Load and add the new menu CMenu mMainMenu; mMainMenu.LoadMenu(IDR_MENU1); ASSERT(mMainMenu); SetMenu(&mMainMenu); } void CShowHideMenuDlg::OnHideMenu() { // Remove and destroy the old menu SetMenu(NULL); ::DestroyMenu(GetMenu()->GetSafeHmenu()); }
问题 5.07 请给我一个 RegEnumValue 的示例? [回到顶部^]
答:ThatsAlok 引用:
首先,看一下 RegEnumKey
。RegEnumKey
看起来像这样:
LONG RegEnumValue( HKEY hKey, // handle to key to query DWORD dwIndex, // index of value to query LPTSTR lpValueName, // value buffer LPDWORD lpcValueName, // size of value buffer LPDWORD lpReserved, // reserved LPDWORD lpType, // type buffer LPBYTE lpData, // data buffer LPDWORD lpcbData // size of data buffer );
现在是一些代码片段:
char szNameOfKey[200];//Buffer DWORD dwBufferSize=200;//Buffer Size DWORD dwIndex=0; CStringArray arrOfKeys;
现在,使用 RegEnumKey
枚举 HKEY_CURRENT_USER
。
while(RegEnumKey(HKEY_CURRENT_USER, // dwIndex++, //Index of Key to be Retrive szNameOfKey,//Buffer of Key dwBufferSize,//Buffer Size NULL,//as documented in MSDN NULL,//We don't need this right NULL,//So no need of it NULL)!= ERROR_NO_MORE_ITEMS) { //add New Found Key to array arrOfKeys.Add(szNameOfKey); //Restucture the size of Buffer as it modified during //Enumeration dwBufferSize=200; } //Now arrOfKeys Hold all the Enumerated Key
问题 5.08 如何禁用/启用属性表中的 OK 按钮? [回到顶部^]
答:R.selvam 引用:
此链接将在此方面有所帮助:破解 CPropertySheet[^]。
问题 5.09 如何获取光盘 (CD) 的序列号? [回到顶部^]
答:Dudi Avramov 引用:
查看:检查 CD 的序列号。
问题 5.10 如何检查远程计算机是否存在? [回到顶部^]
答:DavidCrow 引用:
NetServerGetInfo(L"Computer42", 100, ...)
怎么样?如果计算机不存在,它将返回 ERROR_BAD_NETPATH
。
问题 5.11 如何创建嵌套目录? [回到顶部^]
答:Chris Losinger 引用:
CreateDirectory(top); CreateDirectory(top + "\\subdir1"); CreateDirectory(top + "\\subdir1\\+subdir2");
问题 5.12 如何获取对话框的 HWND? [回到顶部^]
答:Ravi Bhavnani 引用:
您可以通过调用 GetSafeHwnd()
或其成员变量 m_hWnd
来访问其窗口句柄。
问题 5.13 如何知道用户按住按钮的时间是否超过 250 毫秒? [回到顶部^]
答:Gary R. Wheeler 引用:
创建您自己的按钮类 CMyButton
,它继承现有的 CButton
。为 CMyButton
添加 WM_LBUTTONDOWN
消息的处理程序。在处理程序中,向父对话框发送一个通知,如下所示:
WPARAM wParam = MAKEWPARAM(GetDlgCtrlID(),BN_PRESSED); LPARAM lParam = (LPARAM)m_hWnd; GetParent()->PostMessage(WM_COMMAND,wParam,lParam);
其中 BN_PRESSED
是您定义的通知代码。在您的对话框中,添加一个 BN_PRESSED
通知处理程序。在处理程序中,启动一个计时器(尝试使用 QueryPerformanceCounter
)。在您的 BN_CLICKED
处理程序中,获取计时器的值并比较差异。
关注点
没什么可说的,想法和设计取自 **Michael Dunn 先生**(MS Visual C++ MVP)的 CPP Forum FAQ 文章。
请继续关注本系列的更多文章。
特别感谢
- 我的父母。
- 所有活跃的贡献者/Visual C++ 论坛 [CodeProject] 的成员,没有他们,这篇文章就不会问世。
本系列的其他文章
历史
- 2005年6月25日:发布在 CodeProject。
- 2005年6月21日:开始撰写本文。