Jiangsheng的CSDN Digest(June 7, 2006)

为了便于搜索( http://search.csdn.net),这里尽可能保留了论坛上讨论的原文,但是这并不表示本人赞同帖子中的表述方式和观点。

CSDN 讨论总结系列:


为什么很多人都喜欢new一个类,而不是直接声明一个对象呢(C/C++ C++ 语言)


我看很多人写的代码都喜欢这样写(示例)
MyClass* pc = new MyClass();
pc->doSome();
...
delete pc;

为什么非要去new呢?而且这样很容易忘记最后delete。
为什么不按照下面这样呢?
MyClass c;
c.doSome();


指针对象
如果是作为函数的输出参数和返回值传递,可以避免对象的赋值拷贝造成的性能损失按值传递在对象较小时性能较高,甚至可以优化成为寄存器变量
如果需要一个对象的生命期比它所在的代码范围更长,或者需要多处共享这个对象,可能就需要在堆上分配,但是需要考虑内存泄漏如果仅在一个局部作用域中需要使用一个资源,那么可以用栈来实现自动清理工作
用指针可以使用多态 
堆的大小受虚拟内存限制栈的大小受线程限制
可以将创建被聚合的对象的开销延后 
可以所有对被聚合对象的操作转发到一个指针成员变量指向的类的对应函数,这样可以不公开被聚合类的头文件 

如何把自已做的GINA介面,做成XP登陆的风格(VC/MFC 进程/线程/DLL )


http://support.microsoft.com/default.aspx?scid=kb;en-us;322047


如何在游戏中直接使用微软的输入法界面(包括在全屏模式下)(C/C++ 工具平台和程序库 )


The IME uses GDI. In exclusive mode, GDI doesn't have access to the screen (in DX8 graphics), so the IME can't draw. You can dig though Microsoft IME guideline to write your IME window. use LoadLibrary to load a IME(in fact, a DLL),then call the funtions exported by the IME, such as ImmRegisterWord。
On my computer, the file name of MSIME 2003(v6.0.0.2527) is IMSC40A.IME。

参考dx9带的帮助文档,里面详细解释了如果使用ime进行输入法消息拦截,输入法界面自画
Using an Input Method Editor in a Game
http://msdn.microsoft.com/library/en-us/directx9_c/Using_an_Input_Method_Editor_in_a_Game.asp


wav压缩成wma(VC/MFC 基础类 )


you can automate Windows Media Encoder do the conversion, or use Window Media Format SDK to process individual audio samples.

Reference:
Windows Media Audio compressor By Idael Cardoso
http://www.codeproject.com/managedcpp/WmaCompressor.asp


在CMDIChildWnd含有一个CFormView的成员变量m_form, 关闭该CMDIChildWnd窗口时出错(VC/MFC 界面 )


CView objects delete themselves when the windows they are attached to are destroyed by overriding PostNcDestroy and executing a delete this statement. Override again to prevent his behavior if you plan to use it as a stack variable.


Shell COM 从 VC6 移植到 VC2003或2005的问题(VC/MFC ATL/ActiveX/COM)


在VC6中COM映射宏是这么写的:
BEGIN_COM_MAP(CCountLines)
...
COM_INTERFACE_ENTRY(IContextMenu)
...
END_COM_MAP()

COM类,或者叫ATL Object 类是这样继承的:
class ATL_NO_VTABLE CCountLines :
...
public IContextMenu

在VC6中编译/连接都没有问题。
而在VC2003/2005中编译总会提示错误,错误定位在COM映射宏中的 COM_INTERFACE_ENTRY(IContextMenu)
提示信息为:
error C2787: 'IContextMenu' : no GUID has been associated with this object
error C2440: 'initializing' : cannot convert from 'DWORD_PTR' to 'const IID *'
error C2440: 'initializing' : cannot convert from 'ATL::_ATL_CREATORARGFUNC (__stdcall *)' to 'DWORD_PTR'

我试过用其它映射宏来代替 COM_INTERFACE_ENTRY,比如:
COM_INTERFACE_ENTRY_IID()
这样,编译是通过了,可是程序没有效果,也就是说程序不会走到实现 IContextMenu 的接口函数中。

这个问题对于很多 Shell Interface 都遇见过,比如还有 IShellExecuteHook。

还有,VC2003/2005中的 实现COM 类接口的 Wizard 中,选择继承于 shell32.dll 中接口类时,怎么没有 IContextMenu 、IShellExecuteHook 这些类。如果能找到VC2003/2005正确的实现COM 类接口的 Wizard,看看VC是怎么自动生成代码的,也许以上问题就可以解决。


There are two <comdef.h> header files in VC.NET, one in Vc7/include and the other in Vc7/PlatformSDK/include. The former splits off the smart pointer typedefs into comdefsp.h, and it doesn't include IContextMenu. The latter does. You can try to #include the PlatformSDK header directly, change your INCLUDE path order, or supply the missing typedef yourself, e.g.
struct __declspec(uuid("000214e4-0000-0000-c000-000000000046"))
IContextMenu;

_COM_SMARTPTR_TYPEDEF(IContextMenu, __uuidof(IContextMenu));

#include <comdef.h>
#include <initguid.h>
#include <shlobj.h>


简体内码和繁体内码如何相互转换(VC/MFC 基础类)



VC中怎么压缩和修复Access数据库(VC/MFC 数据库)


VC通过ODBC多次删除和插入access数据库,access数据库数据信息还是原来的一样多,但数据库占用的磁盘空间变的越来越大,通过压缩和修复数据库,可以使数据库体积变小,但是怎么通过VC写代码来执行这个操作呢?或者通过怎么设置access数据库让它自己在一个周期里自动进行这个操作呢?Access有退出压缩数据库,但是这样很麻烦的是,要打开数据库,然后关闭的时候才能压缩,如果不打开的话,就无法压缩


Generally we do not recommend using the ODBC API SQLConfigDataSource to compact database:
Q270638 BUG: Database Compaction using SQLConfigDataSource fails
http://support.microsoft.com/support/kb/articles/q270/6/38.asp 

Try to use ADO or OLE DB:
Q230501 HOWTO: Compact Microsoft Access Database via ADO
http://support.microsoft.com/support/kb/articles/q230/5/01.asp 

Q230496 HOWTO: Compacting Microsoft Access Database Through OLE DB
http://support.microsoft.com/support/kb/articles/q230/4/96.asp
 
see also

How to keep a Jet 4.0 database in top working condition
http://support.microsoft.com/?scid=kb;en-us;303528


transformNode后,用webbrowser直接用stream方式加载,css路径就不对了()


如果我把transformNode后的内容保存为html文件,然后用webbrowser去navigate这个文件,是对的,因为html文件里有这句:
<link href="2.css" rel="stylesheet" type="text/css" />
这个css文件和生成的html文件在一个目录下.
但如果我不保存html文件,直接用webbrowser显示transformNode后的内容,发现css没有起作用,
如果我把<link href="2.css" rel="stylesheet" type="text/css" />
里的2.css改成绝对路径,就对了.
因为我不想hardcopy一个绝对路径,也不想动态修改xml和xsl文件,应该怎么办?


The easiest way to do this is to embed a <base> tag into the generated HTML. You don't have to save it to disk, or make visible to the user, just feed it in the stream with the rest of the content.

Another way is to write a custom implementation of IMoniker interface. You only need a non-trivial implementation of two methods: BindToStorage should return the IStream with your HTML content, and GetDisplayName should return the base URL you want to use to resolve relative links.You then use IPersistMoniker to feed the content into MSHTML using this custom implementation, instead of IPersistStreamInit. Disclaimer: I have not done this myself, but I've seen people reporting successful use of this technique.

Changed your LoadFromStream method to QI on the WebBrowser Document for IPersistMoniker then pass your implementation of IMoniker that implemented BindToStorage and GetDisplayName. In BindToStorage you simply use a TStreamAdapter and return the stream.


子类化系统的Save/Open对话框(VC/MFC 基础类)


用过yahoo messenger的人应该知道其Save聊天记录的对话框是系统的对话框,但是明显的进行了子类化或者换肤之类的技术的处理,尝试很久,发现只要设置对话框中的按钮的BS_OWNERDRAW风格,然后截获消息,一概导致程序崩溃。


The problem is that the IDOK and IDCANCEL buttons on the open dialog don't know how to draw itself and MFC isn't passing the message on to your button control. Here is rough code that will allow you to do what you want for the IDOK. It can be cleaned and also applied to the IDCANCEL button:

// Global variables and functions
// Could be incorporated in your class
static WNDPROC oldWndProc;
static CColorButton* pOkButton;

LRESULT CALLBACK MyWndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
if (nMsg == WM_DRAWITEM && wParam == IDOK)
{
pOkButton->SendMessage(WM_DRAWITEM, wParam, lParam); //DrawItem((LPDRAWITEMSTRUCT) lParam);
return 1L;
}

return CallWindowProc(oldWndProc, hWnd, nMsg, wParam, lParam);
}

// Your CFileDialog derived class
BOOL CMyFileDialog::OnInitDialog()
{
// WARNING! Although this is a non-intrusive customization,
// it does rely on unpublished (but easily obtainable)
// information. The Windows common file dialog box implementation
// may be subject to change in future versions of the
// operating systems, and may even be modified by updates of
// future Microsoft applications. This code could break in such
// a case. It is intended to be a demonstration of one way of
// extending the standard functionality of the common dialog boxes.
CFileDialog::OnInitDialog();

//Remember, when you customize the open file dialog,
//your CFileDialog is actually a child of the real dialog,
//which explains why you must use GetParent.
//(For details see article "Give Your Applications the Hot New Interface Look with Cool Menu Buttons"
//in the January 1998 issue of C++Q&A, MSJ.)

CWnd *pWindowDlg = GetParent();

VERIFY(m_btnOK.Attach(IDOK, pWindowDlg, CYAN, BLACK, LTGRAY));

pOkButton = &m_btnOK;

int nButtonStyle;

nButtonStyle = m_btnOK.GetButtonStyle();
m_btnOK.SetButtonStyle(nButtonStyle | BS_OWNERDRAW, FALSE);

oldWndProc = (WNDPROC) SetWindowLong(pWindowDlg->m_hWnd, GWL_WNDPROC,
(DWORD) MyWndProc);

return TRUE;
}

That does it for IDOK only.
 


监控本机的流媒体事件(VC/MFC 基础类)


需要设计一个后台程序,运行在本机上,监控本机上所有流媒体(stream media)的播出状态,举例说, 如果本机上用户运行了Windows Media Player 10, 正在播放mysong.mp3 (可能是本地文件,也可能是连在互联网上的,即通过打开一个URL得到的), 这一个后台程序必须记录该用户开始播放的时间,中间暂停的时间,以及结束的时间.


filemon可以监控网络文件,但是不能监控internet文件
自写的播放器并设置为默认与设计要求不符
监视解码器 
钩住CoCreateInstance不是所有播放器都要调这个函数的,而且钩住了也没有什么用,比如IE中播放音乐,钩住CoCreateInstance只能知道IE运行了,但运行了什么,通过这个方法是无法得知的。
 
Windows Media Player插件仅对window media player有效
在IE中采用监听DOM对象,取得其IWMPCore后,监听其事件仅对IE有效

如何实现“扫描检测硬件改动”VC/MFC 硬件/系统


You can call DeviceIoControl(SCSIHandle, IOCTL_SCSI_RESCAN_BUS, ...) .
See the SPTI sample code in the SDK for a working example.
see also
http://support.microsoft.com/kb/264203



如何获取正在mediamplayer中播放的文件?(在IE中)(.NET技术 VB.NET)


turn off option strict and search for the object tag (it should have a value in the id property that you can use) using the document.all collection. Once you have that, dim a variable which is of type MSHTML.IHTMLObjectElement and set that element to that interface. Then use the object property on the IHTMLObjectElement interface to get a reference to YOUR activex control. You will need to add the HTML object library to your project in order to get the IHTMLObjectElement interface, which is MSHTML.dll in ie4, and MSHTML.tlb in IE5.
see also
http://blog.csdn.net/jiangsheng/archive/2002/08/19/3788.aspx


如何遍历得到IDispatch接口中的全部函数信息?以及事件函数信息(VC/MFC ATL/ActiveX/COM)


如果对象提供了类型库,那么就可以用IDispatch::GetTypeInfo来获取类型信息
参考http://blog.csdn.net/jiangsheng/archive/2003/11/09/3795.aspx


jiangsheng(蒋晟.Net[MVP]) 大哥专题开发/技术/项目 图形图像/机器视觉


近来做图像处理系统,要用到MATLAB7.0和VC.NET2005(基于MFC得多文档结构),遇到了问题,困扰一个礼拜了,请一定帮忙!
问题描述:
在MATLAB7.0中用COMTOOL做成了一个COM组件(.DLL文件),却在VC.NET2005(基于MFC得多文档结构)中总是不能成功加载这个DLL文件,不知为啥?
我在VC.NET的做法是这样的:
1。我是从添加类-ActiveX MFC-“文件”中添加此DLL文件,在工程中可以得到一个类matlabimage。
2。在CXXXVIEW.CPP中包含该类的.h头文件
添加一个菜单的方法
void CXXXView::OnTestTest()
{
// TODO: 在此添加命令处理程序代码
Cmatlabimage i;
i.Create(L"Cmatlabimage",NULL,WS_CHILD,CRect(1,1,50,50),this,101,0);
//101是我在资源符号中随便定义的一个数
i.show();//SHOW是.M里的函数,也就是Cmatlabimage中的一个方法
}
3。编译通过,运行的时候只要点击该菜单就会弹出一个“中断、重试,继续”的对话框,中断后程序定位在
void show()//SHOW是.M里的函数
{
InvokeHelper(0x2, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);
}
4。若对程序单步跟踪到
i.Create(L"Cmatlabimage",NULL,WS_CHILD,CRect(1,1,100,100),this,100,0);
调试信息显示多句提示:0x7c81eb33 (kernel32.dll) 处最可能的异常...
.......
Is the control is properly registered?
察看i的值,都是些0或NULL或无法计算的表达式等。
5。我的控件没有注册成功?可是matlab生成组件时是自动注册的啊,即使手工regsvr32 xx.dll并弹出了注册成功对话框,也还是老样子?
6。我在使用系统自带的一个Calendar控件,用create(...)创建对象实例成功,并能够调用其中的方法。
7。我是从添加类-ActiveX MFC的-“注册表”中添加自带的Calendar,但是自己的控件在添加类-ActiveX MFC的-“注册表”项中找不到,是从添加类-ActiveX MFC的-“文件”中添加的。


You probably did not design your ActiveX as "insertable". Check MATLAB7.0 references to see if it supports insertable ActiveX developing. if not, use MFC/ATL ActiveX Wizard in Visual C++, and make sure the insertable option is selected.

reference
http://msdn.microsoft.com/msdnmag/issues/0400/mfc/
 


如何实时获取IE网页输入框(用户名和密码)VC/MFC 基础类


如果只是获取IE网页的用户名和密码,倒是很简单,枚举IE表单就够了。但是问题是,如何对IE加以控制,在合适的时机进行枚举。

我一开始打算用BHO来得到这样的时机。但是研究过BHO后,我发现比较困难。用BHO只能得到post后的数据,而这时用户名和密码都被加密了。我想得到这样一种通知,IE开始跳转,但是还没有开始下载文档。在得到这样通知的时候开始枚举表单。
如果进行循环枚举的话,系统的效率就实在太低了。


IE不允许扩展在BeforeNavigate2事件处理中修改表单数据。尽管你可以取消这个事件并且调用Navigate2方法,但是这种替换方法获得的提交结果并不总是和原来的提交行为相同(比如启用viewstate的asp.net页面会丢失状态)。另外,需要判断是IE还是扩展在提交表单以避免死循环。

另外一种方法是截获form的onsubmit事件。这种方法的缺点是需要截获的form可能在框架中,而跨框架访问HTML元素经常是被禁止的。另外,一些网页,例如包含asp.net客户端验证脚本的网页也需要截获form的onsubmit事件。另外一个需要注意的是,基于安全性考虑,input type=file的值是不可以编程访问的。
IE跳转时不调用API的,调用的都是webbrower控件的事件.你可以获取IHTMLDocument2指针,然后枚举所有Frame:

void EnumFrame( IHTMLDocument2 * pIHTMLDocument2 )
{
if ( !pIHTMLDocument2 )return;

HRESULT hr;

CComPtr< IHTMLFramesCollection2 > spFramesCollection2;
pIHTMLDocument2->get_frames( &spFramesCollection2 );//取得框架frame的集合

long nFrameCount=0;//取得子框架个数
hr = spFramesCollection2->get_length( &nFrameCount );
if ( FAILED ( hr ) || 0 == nFrameCount )return;

for(long i=0; i<nFrameCount; i++)
{
CComVariant vDispWin2;//取得子框架的自动化接口
hr = spFramesCollection2->item( &CComVariant(i), &vDispWin2 );
if ( FAILED ( hr ) )continue;

CComQIPtr< IHTMLWindow2 > spWin2 = vDispWin2.pdispVal;
if( !spWin2 )continue;//取得子框架的 IHTMLWindow2 接口

CComPtr < IHTMLDocument2 > spDoc2;
spWin2->get_document( &spDoc2 );//取得子框架的 IHTMLDocument2 接口

EnumForm( spDoc2 );//递归枚举当前子框架 IHTMLDocument2 上的表单form
}
}

//然后每个Frame里都枚举From,并枚举所有元素:
//你只需要再判断是否为用户名输入框及密码输入框,即可,然后替换其文字
//代码后面,已经帮处理了其它所有工作,你只要pForm->submit();即可
//这样的提交可是IE真实的提交动作,并非你上面想要的"替换方法获得的提交结果"
//所以这种方法可以说是完美的,唯一不足的地方就是,名字输入框等只能靠一些通用的命名文式命名的才能确定是名字输入框,例如,我将输入框命名为USERNAME或USERID或LOGINNAME,LOGINID等都可以一下就确认是名字输入框,但如果有些人比较BT,命名为RegNumber(注册号)即以注册号作为用户名登录或学号(StudentNo)等作为用户名,你就分辩率不出来了,所以这种情况下就不如"替换方法获得的提交结果"的方法来得正确.
//对输入框的判断就留给你自己了,思路及代码已经很完整了,我想应该没有什么问题了.
//祝成功!
void EnumForm( IHTMLDocument2 * pIHTMLDocument2 )
{
if( !pIHTMLDocument2 )return;
USES_CONVERSION;
EnumFrame( pIHTMLDocument2 );//递归枚举当前 IHTMLDocument2 上的子框架fram

CComQIPtr< IHTMLElementCollection > spElementCollection;
hr = pIHTMLDocument2->get_forms( &spElementCollection );//取得表单集合
if ( FAILED( hr ) )
{
cout << _T("获取表单的集合 IHTMLElementCollection 错误") << endl;
return;
}

long nFormCount=0;//取得表单数目
hr = spElementCollection->get_length( &nFormCount );
if ( FAILED( hr ) )
{
cout << _T("获取表单数目错误") << endl;
return;
}

for(long i=0; i<nFormCount; i++)
{
IDispatch *pDisp = NULL;//取得第 i 项表单
hr = spElementCollection->item( CComVariant( i ), CComVariant(), &pDisp );
if ( FAILED( hr ) )continue;

CComQIPtr< IHTMLFormElement > spFormElement = pDisp;
pDisp->Release();

long nElemCount=0;//取得表单中 域 的数目
hr = spFormElement->get_length( &nElemCount );
if ( FAILED( hr ) )continue;

for(long j=0; j<nElemCount; j++)
{
CComDispatchDriver spInputElement;//取得第 j 项表单域
hr = spFormElement->item( CComVariant( j ), CComVariant(), &spInputElement );
if ( FAILED( hr ) )continue;

CComVariant vName,vVal,vType;//取得表单域的 名,值,类型
hr = spInputElement.GetPropertyByName( L"name", &vName );
if( FAILED( hr ) )continue;
hr = spInputElement.GetPropertyByName( L"value", &vVal );
if( FAILED( hr ) )continue;
hr = spInputElement.GetPropertyByName( L"type", &vType );
if( FAILED( hr ) )continue;

LPCTSTR lpName = vName.bstrVal?
OLE2CT( vName.bstrVal ) : _T("NULL");//未知域名
LPCTSTR lpVal = vVal.bstrVal?
OLE2CT( vVal.bstrVal ) : _T("NULL");//空值,未输入
LPCTSTR lpType = vType.bstrVal?
OLE2CT( vType.bstrVal ) : _T("NULL");//未知类型

cout << _T("[") << lpType << _T("] ");
cout << lpName << _T(" = ") << lpVal << endl;

}

//这里提交这个表单
pForm->submit();


}
}
参考
http://msdn.microsoft.com/workshop/browser/mshtml/tutorials/sink.asp


如何改变WINXP的一些默认路径(Windows专区 Windows NT/2000/XP/2003 )


目的,想把WINXP设一个普通用户(或指定用户)登录使用后,不能对(C盘系统盘)写.但可正常使用.读给几个意见跟如何做,谢谢.
想法有如下几个请教如何做?
1.把 Documents and Settings 路径设到D盘.(也方便备份与安全)
2.把IE等一些临时文件夹目录也改到D盘.并如不是管理员不准更改IE设置,收藏夹除外(这样除了用管理员装软件,C盘不用变大,不受病毒等影响,也不会给一些网站或什么随便装或改变我的IE等设置)
3.微软的默认目录TEMP当然也要改到D盘.


http://support.microsoft.com/?kbid=322014 


一个程序如IE设置为默认浏览器后,当双击一个HTM文件或用脚本WINDOW.OPEN打开网页时,这个程序(IE)会收到怎样的调用. (VC/MFC HTML/XML )


也就是说,如果我把我的程序设为默认浏览器,在程序中怎么才能处理WINDOW.OPEN打开


DDE is the way the shell tells a running instance of a program to do something. You don't have to make your program use DDE, but if you don't it must start a new instance every time. Somehow you have to have a mechanism for the shell to tell your program what it wants you to do. If you are not using DDE then it will have to be by switches or something on the command line. Just sending a file name parameter is not precise enough. The registry has lots of protocol entries as well as file associations. Not all the protocols are handled by IE, some are done by rundll. You can choose which operations will be done by your browser by only changing the registry entries for those things.

http://support.microsoft.com/kb/q177054/
http://support.microsoft.com/kb/q175306/

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值