我正在尝试使用本机Windows消息队列系统(没有.NET)使用C/C++创建一个简单的窗口.我按照MSDN教程编写了一些创建空窗口的基本代码:
void main()
{
HINSTANCE hinst;
HWND hwndMain;
WNDCLASSEX wnd;
MSG msg;
hinst = GetModuleHandle( NULL );
memset( &wnd, 0, sizeof( wnd ) );
wnd.cbSize = sizeof( wnd );
wnd.lpszClassName = "MainWClass";
wnd.lpfnWndProc = MainWProc;
wnd.hInstance = hinst;
int result = RegisterClassEx( &wnd );
if( !result )
{
printf("RegisterClassEx error: %d\r\n", GetLastError() );
}
hwndMain = CreateWindowEx
(
0, //extended styles
wnd.lpszClassName, //class name
"Main Window", //window name
WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL | WS_MINIMIZEBOX, //style tags
CW_USEDEFAULT, //horizontal position …Run Code Online (Sandbox Code Playgroud) 在Visual C++ 2008 Express中,当我创建一个新的控制台项目时,我得到以下程序:
//Explodey.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
int _tmain(int argc,_TCHAR* argv[])
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我有几个问题:
为什么主函数_tmain而不是main?
我认为该argv参数应该是char* argv[]代替_TCHAR.
什么stdafx.h?
这并不像我习惯的C++那样.
让我们搞乱非常基本的动态分配内存.我们取3的向量,设置其元素并返回向量的总和.
在第一个测试用例中,我使用带new[]/ 的原始指针delete[].在我使用的第二个std::vector:
#include <vector>
int main()
{
//int *v = new int[3]; // (1)
auto v = std::vector<int>(3); // (2)
for (int i = 0; i < 3; ++i)
v[i] = i + 1;
int s = 0;
for (int i = 0; i < 3; ++i)
s += v[i];
//delete[] v; // (1)
return s;
}
Run Code Online (Sandbox Code Playgroud)
大会(1)(new[]/ delete[])
main: # @main
mov eax, 6
ret
Run Code Online (Sandbox Code Playgroud)
大会(2)(std::vector)
main: …Run Code Online (Sandbox Code Playgroud) 使用COM时,我通常依赖于ATL智能指针,如ATL::CComPtr和ATL::CComBSTR,用于资源管理.但是我正在调用的一些方法使用输出参数来返回指向我必须释放的已分配存储的指针.例如:
WCHAR *pszName = nullptr;
if (SUCCEEDED(pShellItem->GetDisplayName(SIGDN_FILESYSPATH, &pszName))) {
DoSomething(pszName);
CoTaskMemFree(pszName);
}
Run Code Online (Sandbox Code Playgroud)
请注意,GetDisplayName为字符串分配内存并通过输出参数返回指向它的指针.调用者有责任释放内存CoTaskMemFree.
如果DoSomething抛出异常,则上述代码将泄漏.我想使用某种智能指针pszName来避免这种泄漏,但API需要WCHAR**,所以我不知道除了哑指针的地址之外我怎么能传递.由于我不是那个分配,我不能使用RAII.
如果我可以像这样制作一个删除器,我可以使用RRID:
struct CoTaskMemDeleter {
void operator()(void *p) { ::CoTaskMemFree(p); }
};
Run Code Online (Sandbox Code Playgroud)
然后立即将返回的指针分配给标准智能指针,如下所示:
WCHAR *pszName = nullptr;
if (SUCCEEDED(pShellItem->GetDisplayName(SIGDN_FILESYSPATH, &pszName))) {
std::unique_ptr<WCHAR, CoTaskMemDeleter> guard(pszName);
DoSomething(pszName);
}
Run Code Online (Sandbox Code Playgroud)
这样可行,但似乎容易引入额外的保护变量.例如,这种方法pszName指向释放的内存,因此很容易意外地再次使用它.
对于输出参数返回的COM服务器分配的内存,是否有更简洁的方法来使用智能指针或RAII包装器?我错过了ATL提供的东西吗?
有没有办法使用Windows API来检测特定显示器是投影仪(投影仪)而不是屏幕?
(我正在编写一个投影映射桌面应用程序,我希望它能自动检测投影机是否已连接并处于活动状态,以便用户将现实与预览进行比较.)
我已经使用EnumDisplayMonitors和EnumDisplayDevices来查找监视器,但我找不到任何标志或其他显示类型的指示.我查看了DEVMODE和DISPLAY_DEVICE以及后者指向的注册表项.我没有看到可以区分屏幕和投影仪的DeviceCapabilities或GetDeviceCaps调用.我还查看了设备管理器,看看是否有一个属性区分我的常规显示器和投影机,但我找不到任何东西.所以也许没有办法做到这一点.
但是,屏幕分辨率控制面板小程序将投影机识别为"PROJECTOR",同时将我的主显示器识别为"Dell U3011".使用EnumDisplayDevices,我可以从DISPLAY_DEVICE获得"Dell U3011"字符串,但是,对于投影仪,我只得到"Generic PnP Monitor".不知何故,小程序必须在其他地方寻找获得"PROJECTOR"字符串,或者它显示"PROJECTOR"用于任何似乎是投影仪的通用PnP监视器.那它看起来在哪里,它是如何知道的?
C ++ 20将指定带符号整数类型必须使用二进制补码。鉴于(实际上?)每个实现当前都使用二进制补码,这似乎不是一个很大的变化。
但是我想知道这种改变是否会将某些“未定义的行为”转变为“实现定义”甚至“定义”。
考虑绝对值函数std::abs(int)及其一些重载。C ++标准通过引用C标准来包括此功能,该标准表示如果无法表示结果,则行为未定义。
用二进制补码时,没有与之相对应的正数INT_MIN:
abs(INT_MIN) == -INT_MIN == undefined behavior
Run Code Online (Sandbox Code Playgroud)
在符号幅度表示中,有:
-INT_MIN == INT_MAX
Run Code Online (Sandbox Code Playgroud)
因此,abs()留下一些未定义的行为似乎是合理的。
一旦需要二进制补码,abs(INT_MIN)就可以完全指定行为,或者至少定义实现,这似乎是有意义的,而没有任何向后兼容的问题。但我看不到有任何建议的改变。
我看到的唯一缺点是C ++标准将需要abs()明确指定,而不是引用C标准的abs()。(据我所知,C并不要求补码。)
这是否只是委员会的优先事项?还是有理由不利用两国补编任务规定所提供的简化和确定性?
我有一个绘图功能,只需要一个HDC.但是我需要展示一个精确版本的打印版本.
所以目前,我使用带有打印机HDC的CreateCompatibleDC()和带有打印机HDC的CreateCompatibleBitmap().
我这样想DC会有打印机的确切宽度和高度.当我在这个HDC中选择字体时,文本将与打印机完全一样.
不幸的是,我不能让StretchBlt()将这个HDC的像素复制到控件的HDC,因为我猜它们是不同的HDC类型.
如果我从具有与打印机页面相同的w,h的HDC窗口创建"内存画布",那么这些字体会因为缩放屏幕而不是页面而显示出来.
我应该从窗口的DC和CreateCompatibleBitmap()从打印机的DC或其他东西创建CompatibleDC()吗?
如果有人可以解释这样做的正确方法.(并且仍然有像打印机那样看起来很完美的东西)......
好吧,我很感激!!
...史蒂夫
我正在以两种方式对我的汽车阵列进行排序.一年一年,如下所示.和另一个由make.Make是一个char*如果我只是指向它们,我如何比较字符串?
int i, j;
for(i=0; i<100; i++){
for(j=0; j<100-i; j++){
if(carArray[i]!=NULL && carArray[j]!= NULL && carArray[j+1]!=NULL){
if(carArray[i]->year > carArray[j+1]->year){
swap(carArray[j], carArray[j+1]);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
上述方法适用于int(年).如何使它适用于char指针?
我一直在使用Double Metaphone和Caverphone2进行字符串比较,它们在名称,地址等方面做得很好(Caverphone2对我来说效果最好).但是,当您获得数字值时,例如电话号码,IP地址,信用卡号等,它们会产生太多的误报.
所以我看了Luhn和Verhoeff算法,它们基本上描述了我想要的东西,但并不完全.他们似乎擅长验证,但似乎并不是为模糊匹配而构建的.有什么行为像Luhn和Verhoeff,它可以检测到涉及两个相邻数字的单位错误和换位错误,用于编码和比较目的,类似于模糊字符串算法?
我想对一个数字进行编码,然后将其与100,000个其他数字进行比较,以找到完全相同的匹配.因此像7041234这样的东西会与7041324匹配作为可能的转录错误,但像4213704这样的东西不会.
我有一个C++类,我正在用一些C文件编译它.
我想调用一个用C++定义的函数,实际上是在C++类中,所以我该怎么做?
以下声明显示我在说什么:可能存在语法错误:
serial_comm.cpp
class MyClass {
void sendCommandToSerialDevice(int Command, int Parameters, int DeviceId) {
//some codes that write to serial port.
}
}
Run Code Online (Sandbox Code Playgroud)
external.c
int main(int argc, char ** argv) {
//what am I going to write here?
}
Run Code Online (Sandbox Code Playgroud)