⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 visual c++编程技巧.txt

📁 Visual C++编程技巧.txt Visual C++编程技巧.txt
💻 TXT
📖 第 1 页 / 共 5 页
字号:

//TODO-process system menu item 

} 

else 

CMDIFrameWnd:: OnSysCommand (nID, lParam); 

} 

最后,一个设计良好的UI应用程序应当在系统菜单项加亮时在状态条显示一个帮助信息,这可以通过增加一个包含系统菜单基ID的串表的入口来实现。 

59、如何确定顶层菜单所占据的菜单行数 

这可以通过简单的减法和除法来实现。首先,用户需要计算主框窗口的高度和客户区;其次,从主框窗口的高度中减去客户区、框边界以及标题的高度;最后,除以菜单栏的高度。下例成员函数是一个计算主框菜单所占据的行数的代码实现。 

int CMainFrame:: GetMenuRows () 

{ 

CRect rcFrame,rcClient; 

GetWindowRect (rcFrame); 

GetClientRect (rcClient); 

return (rcFrame.Height () -rcClient.Height ()- 

:: GetSystemMetrics (SM_CYCAPTION) - 

(:: getSystemMetrics (SM_CYFRAME) *2)) / 

:: GetSystemMetrics (SM_CYMENU); 

} 

60、在用户环境中如何确定系统显示元素的颜色 

调用SDK函数GetSysColor可以获取一个特定显示元素的颜色。下例说明了如何在MFC函数CMainFrameWnd:: OnNcPaint中调用该函数设置窗口标题颜色。 

void CMiniFrameWnd:: OnNcPaint () 

{ 


dc.SetTextColor (:: GetSysColor (m_bActive ? 

COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT)); 


} 

61、如何查询和设置系统参数 

在Windows 3.1 SDK中介绍过SDK函数SystemParametersInfo,调用该函数可以查询和设置系统参数,诸如按键的重复速率设置、鼠标双击延迟时间、图标字体以及桌面覆盖位图等等。 

//Create a font that is used for icon titles. 

LOGFONT stFont; 

:: SystemParametersInfo (SPIF_GETICONTITLELOGFONT, 

sizeof (LOGFONT), &stFont, SPIF_SENDWININICHANGE); 

m_font.CreateFontIndirect (&stFont); 

//Change the wallpaper to leaves.bmp. 

:: SystemParametersInfo (SPI_SETDESKWALLPAPER, 0, 

_T (" forest.bmp"), SPIF_UPDATEINIFILE); 

62、如何使用一个预定义的Windows光标 

调用CWinApp:: LoadStandardCursor并传送光标标识符。 

BOOL CSampleDialog:: OnSetCursor (CWnd* pWnd, UINT nHitTest, UINT message) 

{ 

//Display wait cursor if busy. 

if (m_bBusy) 

{ 

SetCursor (AfxGetApp () ->LoadStandardCursor (IDC_WAIT)); 

return TRUE; 

} 

return CDialog:: OnSetCursor (pWnd. nHitTest,message); 

} 

63、如何确定当前屏幕分辨率 

调用SDK函数GetSystemMetrics,该函数可以检索有关windows显示信息,诸如标题大小、边界大小以及滚动条大小等等。 

//Initialize CSize object with screen size. 

CSize sizeScreen (GetSystemMetrics (SM_CXSCREEN), 

GetSystemMetrics (SM_CYSCREEN)); 

64、如何检索原先的Task Manager应用程序使用的任务列表 

原先的Task Manager应用程序显示顶层窗口的列表。为了显示该列表,窗口 

必须可见、包含一个标题以及不能被其他窗口拥有。调用CWnd:: GetWindow可以 

检索顶层窗口的列表,调用IsWindowVisible、GetWindowTextLength以及GetOwner 

可以确定窗口是否应该在列表中。下例将把TaskManager窗口的标题填充到列表中。 

void GetTadkList (CListBox&list) 

{ 

CString strCaption; //Caption of window. 

list.ResetContent (); //Clear list box. 

//Get first Window in window list. 

ASSERT_VALID (AfxGetMainWnd ()); 

CWnd* pWnd=AfxGetMainWnd () ->GetWindow (GW_HWNDFIRST); 

//Walk window list. 

while (pWnd) 

{ 

// I window visible, has a caption, and does not have an owner? 

if (pWnd ->IsWindowVisible () && 

pWnd ->GetWindowTextLength () &&! pWnd ->GetOwner ()) 

{ 

//Add caption o window to list box. 

pWnd ->GetWindowText (strCaption); 

list.AddString (strCaption); 

} 

//Get next window in window list. 

pWnd=pWnd->GetWindow (GW_HWNDNEXT); 

} 

} 

65、如何确定Windows和Windows系统目录 

有两个SDK函数可以完成该功能。GetWindowsDirectory和GetSystemDirectory,下例说明了如何使用这两个函数: 

TCHAR szDir [MAX_PATH]; 

//Get the full path of the windows directory. 

:: GetWindowsDirectory (szDir, MAX_PATH); 

TRACE ("Windows directory %s\n", szDir); 

//Get the full path of the windows system directory. 

:: GetSystemDirectory (szDir, MAX_PATH); 

TRACE ("Windows system directory %s\n", szDir); 

66、在哪儿创建临文件 

调用SDK函数GetTemPath可以确定临时文件的目录,该函数首先为临时路径检测TMP环境变量:如果没有指定TMP,检测TMP环境变量,然后返回到当前目录。下例说明了如何创建一个临时文件。 


//get unique temporary file. 

CString strFile; 

GetUniqueTempName (strFile); 

TRY 

{ 

//Create file and write data.Note that file is closed 

//in the destructor of the CFile object. 

CFile file (strFile,CFile:: modeCreate | CFile:: modeWrite); 

//write data 

} 

CATCH (CFileException, e) 

{ 

//error opening file 

} 

END_CATCH 


Void GetuniqueTempName (CString& strTempName) 

{ 

//Get the temporary files directory. 

TCHAR szTempPath [MAX_PATH]; 

DWORD dwResult=:: GetTempPath (MAX_PATH, szTempPath); 

ASSERT (dwResult); 

//Create a unique temporary file. 

TCHAR szTempFile [MAX_PATH]; 

UINT nResult=GetTempFileName (szTempPath, _T ("~ex"),0,szTempfile); 

ASSERT (nResult); 

strTempName=szTempFile; 

} 

67、如何访问桌面窗口 

静态函数CWnd:: GetDesktopWindow 返回桌面窗口的指针。下例说明了MFC函数CFrameWnd::BeginModalStae是如何使用该函数进入内部窗口列表的。 

void CFrameWnd::BeginModalState () 

{ 


//first count all windows that need to be disabled 

UINT nCount=0; 

HWND hWnd=:: GetWindow (:: GetDesktopWindow (), GW_CHILD); 

while (hWnd!=NULL) 

{ 

if (:: IsWindowEnabled (hwnd) && 

CWnd::FromHandlePermanent (hWnd)!=NULL && 

AfxIsDescendant (pParent->m_hWnd, hWnd) && 

:: SendMessage (hWnd, WM_DISABLEMODAL, 0, 0)==0) 

{ 

++nCount; 

} 

hWnd=:: GetWindow (hWnd, GW_HWNDNEXT); 

} 


} 


--------------------------------------------------------------------------------

 
Visual C++编程小技巧之九 

68. VC1.5下如何跳到第一事例? 

69. 为什么VC++2.0中使用文件对话框会死机? 

70. 在VC++1.5中如何new一个大数组? 

71. 在VC1.5中,如何得到子窗口在主窗口中的相对坐标? 

72. VC1.5 如何调用进程? 

73. VC++1.5编Win3.1程序能否实现全局跳转? 

74. 如何在DLL用自定义窗口? 

75. 如何让TOOLTIP的字体变大? 

  

68.VC1.5下如何跳到第一事例? 

各位大虾: CWinApp::InitInstance()中可知是第二事例,但如何在return FALSE; 

之前FindWindow()到第一事例呢? 主要困难是: 

1).主窗口类名可否得到 ( 主窗口==MainFrame ? 若是,怎知MainFrame类名? 

2).Title因含有文档名, 是一不确定串. 

1. 类名是动态的,所以应该不易得到。(不知是否如此?) 

类名不是动态的,如果不作处理, MFC 总是使用 AfxFrameOrView 为类名, 

只有 MainFrame, 和 View 等等才会用 AfxFrameOrView, 

我刚用 spy 看了我的一个程序,主窗口的Class 为 Afx:b:13ce:6:3be7 

至于如何注册自己定义的类,我还没有学会,望高手指教。 

AfxRegisterWndClass() 

2. 我用的方法是只查Title中前半部分和你的要求串一致即可,忽略后面的文档? 

FindWindow() 函数需要给定窗口类名和窗口标题(Title),不知你是怎样做到只查前半部分的? 

用EnumWindows()一个窗口一个窗口查,不能用 FindWindow() 

这里我有另外一个问题: 

找到第一事例的窗口后,如何激活它,使它成为当前窗口? 

极小状态时,才能把它激活出来,否则也是没有动静,不知何故? 

if (IsIconic(hwndMain)) 

ShowWindow(hwndMain, SW_RESTORE); 

else 

SetActiveWindow(hwndMain); 

  

69.关于VC++2.0中使用文件对话框的求助 

在VC++2.0中使用了标准文件对话框以后,编译联接都能正常通过,而且使用Ctrl+F5执行EXE文件也完全正常,但是一旦用F5调试进入, 使用该对话框的代码时,Win95就会异常中止,请问各位高手,为什么? 

文件对话框,改变了执行程序的当前路径,从而干扰了调试系统。如果是为了调试,可以使文件对话框定位在当前目录,并且运行时不要在其中改变目录。 

  

70.如何用VC2.0编写能Edit超过64K的类 

我要用 VC2.0 编写一个 Editor, 要求能编辑超过 64K 的文本.我的 Edit 类从 CEdit 类派生出来 , 但编辑超过 64K 的文本就显示不出来. 原知道在 VC1.5 中 CEdit 类只能编辑小于 64K 的文本,不知 VC2.0 是否也一样? 

. 

自己从CWnd类派生,管理内存、输入、显示等(其实不累)。至于从CEdit中派生,我也没有头绪。 

VC2.0会有这事?我没试过,但我不相信。VC2.0是运行在Win95或WindowsNT 上的开发工具,是Win32的开发工具。Windows 95及NT对应用程序在内存上没有段的限制,应用程序最多可利用高达4G的内存(包括系统占用)。你所说的限制大概是VC1.5的限制吧。盖因VC1.5运行于Win16上,每个段不能超过64K。 

的确如此,VC2.0 有两个例子 samples\mfc\multipad 和 samples\mfc\superpad 也是如此。不信你看看。 

  

71.在VC++1.5中如何new一个大数组 

我想在用VC++1.5编程时,new一个[512][512]的大数组,却总是不行. 

哪位专家可以指点一下. 

选用Larger and Huger模式的库编译 

我用过Large模式,好象不行呀!我用Huge模式,头文件编译时就出错了! 

VC++ 1.5 毕竟是16的, 512*512 是多少?做链表好了否则就用VC++2.0, 全32位就不该有这问题了 

这样的做法并不十分好,要分配如此大的内存最好用全局的内存分配函数.直接用指针操作,效率也会提高. 

用MFC类不行吗?如CObArray 

请用GlobalAllocPtr和GlobalFreePtr这一对函数,如下: 

DWORD dwSize ;; 

hpsStr =(char huge *)GlobalAllocPtr( GMEM_MOVEABLE , dwSize ) ; 

... 

GlobalFreePtr( hpsStr ) ; 

不管多大数组,都保证没有问题。 

在VC1.5中,如何得到子窗口在主窗口中的相对坐标? 

比较笨的方法是先ClientToScreen转成屏幕坐标,然后ScreenToClient转成主窗口坐标,不知有没有更方便的方法. 

MapWindowPoints(hwndChild, hwndParent, (POINT FAR *)lprc, 2)lprc 设成子窗口内的坐标(0,0, width, height) 

  

72.VC1.5 如何调用进程? 

我用VC1.52编Windows程序,中间想执行一个其他Windows应用程序,并且让我的程序挂起等应用程序执行完后再继续,请问如何实现? 

exec( ) 和 spawn( )与Windows不兼容,所以它们肯定不行了. 

WinExec() 

挂起的一个简单方法是得到新进程的主窗口句柄,然后进入死循环,直到此句柄变为无效。 

不知道还有什么更漂亮一些的手法。 

请问,怎么得到进程的主窗口句柄呢? 

是呀,我也正想问呢.例如我执行的是PSpice for Windows.用WinExec() 

可以如下: 

int nWinRun = WinExec("wpspice test.cir", SW_SHOWNORMAL); 

可是如何得到新进程的主窗口句柄呢?能不能截取新进程的消息呢 

紧接着用 GetActiveWindow() 就可以. 

当然还是在win3.1 下才有用.... 

win95 下由于有输入的局部化问题,所以只能得到本线程的Activate Window或Focus Window,对于其他情况返回都是NULL.这问题还是不知道怎么办,alas... 

所 以 最 根 本 的 办 法 是 如 何 读 写 Windows 消 息 总 库 . 

哪 位 高 手 看 得 懂 SPY 的 源 程 序 (在 C++ 或 Delphi 之 类 的 Sample 中 有 ). 

Use "FindWindow()". according to window title, get window handle. 

then use Window Declassing method. that is write your own procedure 

to process the message you want to capture. "CallWindowProc() is 

executed before DefWindowProc()". (sorry can not type chinese now.) 

我在Vc 4.0 下用_exec, _spawn, 以及WinExec都没问题的! 

  

73.VC++1.5编Win3.1程序能否实现全局跳转? 

setjmp即可,和DOS下一样。 

用Windows API 中的 Catch() 和 Throw() 可能会更好些。不过我也不知道和setjmp有些什么区别。 

setjmp 恐怕不行, 它好象只能用来编写 C 程序,而不能用来编写 C++ 程序! 

我的感觉是,只要是代码段,可以不受函数和应用的限制,随便乱跳的。其实是数据段,也可以跳过去的。换句话说,在WINDOW中,可以跳到任何地方,只要我乐意。 

  

74.在DLL用自定义窗口 

我在DLL中用如下窗口, 

class CMyWin:public CWnd 

{ 

public: 

CMyWin() ; 

} ; 

CMyWin::CMyWin() 

{ 

if( !CreateEx( WS_EX_TOPMOST , 

AfxRegisterWndClass( CS_SAVEBITS ) , 

"mywin" , WS_POPUP , 

0 , 0 , 100 , 100 , NULL , NULL ) ) 

AfxMessageBox( "CreateEx error" ) ; 

} 

请问有谁知道是什么原因?谁在DL

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -