Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1612820
  • 博文数量: 585
  • 博客积分: 14610
  • 博客等级: 上将
  • 技术积分: 7402
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-15 10:52
文章存档

2013年(5)

2012年(214)

2011年(56)

2010年(66)

2009年(44)

2008年(200)

分类: C/C++

2012-01-27 03:07:34

Visual C++ 编程技巧之七、八和九
分类: 2.3 VC技巧收集 258人阅读 评论(0) 收藏 举报

49、如何实现一个橡皮区矩形 
50、如何更新翻转背景颜色的文本 
51、如何创建一个具有特定点大小的字体 
52、如何计算一个串的大小 
53、如何显示旋转文本 
54、如何正确显示包含标签字符的串 
55、串太长时如何在其末尾显示一个省略号 
56、如何快速地格式化一个CString对象 
57、为什么即使调用EnableMenuItem菜单项后,菜单项还处于禁止状态 
58、如何给系统菜单添加一个菜单项 
59、如何确定顶层菜单所占据的菜单行数 
60、在用户环境中如何确定系统显示元素的颜色 
61、如何查询和设置系统参数 
62、如何使用一个预定义的Windows光标 
63、如何确定当前屏幕分辨率 
64、如何检索原先的Task Manager应用程序使用的任务列表 
65、如何确定Windows和Windows系统目录 
66、在哪儿创建临文件 
67、如何访问桌面窗口 
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的字体变大?

49、如何实现一个橡皮区矩形  
 
CRectTracker是一个很有用的类,可以通过调用CRectTracker:: TrackRubberBand响应WM_LBUTTONDOWN消息来创建一个橡皮区矩形。下例表明使用CRectTracker移动和重置视窗中的蓝色椭圆的大小是很容易的事情。  
首先,在文件档中声明一个CRectTracker数据成员:  
 
class CSampleView : Public CView  
{  
    …  
    public :  
    CrectTracker m_tracker;  
    …  
};  
 
其次,在文档类的构造函数中初始化CRectTracker 对象:  
 
CSampleDoc:: CSampleDOC ()  
{  
    //Initialize tracker position, size and style.  
    m_tracker.m_rect.SetRect (001010);  
    m_tracker.m_nStyle=CRectTracker:: resizeInside |  
    CRectTracker:: dottedLine;  
}  
 
然后,在OnDraw函数中画椭圆和踪迹矩形:  
 
void CSampleView:: OnDraw (CDC* pDC)  
{  
    CSampleDoc* pDoc=GetDocument ();  
    ASSERT_VALID (pDoc);  
    //Select blue brush into device context.  
    CBrush brush (RGB (00255));  
    CBrush* pOldBrush=pDC->SelectObject (&brush); 
    //draw ellipse in tracking rectangle.  
    Crect rcEllipse;  
    pDoc->m_tracker.GetTrueRect (rcEllipse);  
    pDC->Ellipse (rcEllipse);  
    //Draw tracking rectangle.  
    pDoc->m_tracker.Draw (pDC);  
    //Select blue brush out of device context.  
    pDC->Selectobject (pOldBrush);  
}  
 
最后,使用ClassWizard处理WM_LBUTTONDOWN消息,并增加下述代码。该段代码根据鼠标击键情况可以拖放、移动或者重置椭圆的大小。  
 
void CSampleView::OnLButtonDown (UINT nFlags, CPoint point)  
{  
    //Get pointer to document.  
    CSampleDoc* pDoc=GetDocument ();  
    ASSERT_VALID (pDoc);  
    //If clicked on ellipse, drag or resize it. Otherwise create a  
    //rubber-band rectangle nd create a new ellipse.  
    BOOL bResult=pDoc->m_tracker.HitTest (point)!= CRectTracker::hitNothing;  
    //Tracker rectangle changed so update views.  
    if (bResult)  
    {  
        pDoc->m_tracker.Track (this,point,TRue);  
        pDoc->SetModifiedFlag ();  
        pDoc->UpdateAllViews (NULL);  
    }  
    else  
        pDoc->m-tracker.TrackRubberBand (this,point,TRUE);  
    CView:: onLButtonDown (nFlags,point);  
}  
 
50、如何更新翻转背景颜色的文本  
 
调用CDC:: SetBkmode并传送OPAQUE用当前的背景颜色填充背景,或者调用CDC::SetBkMode并传送TRANSPAARENT使背景保持不变,这两种方法都可以设置背景模式。下例设置背景模式为TRANSPARENT,可以两次更新串,用花色带黑阴影更新文本。黑色串在红色串之后,但由于设置了背景模式仍然可见。  
 
void CSampleView:: OnDraw (CDC* pDC)  
{  
    //Determint size of view.  
    CRect rcView;  
    GetClientRect (rcVieew);  
    //Create sample string to display.  
    CString str (_T ("Awesome Shadow Text..."));  
    //Set the background mode to transparent.  
    pDC->SetBKMode (TRANSPARENT);  
    //Draw black shadow text.  
    rcView.OffsetRect (11);  
    pDc->SetTextColor (RGB (000));  
    pDC->DrawText (str, str.GetLength (), rcView, DT_SINGLELINE | DT_CENTER | DT_VCENTER);  
    //Draw red text.  
    rcView.OffsetRect (-1,-1);  
    pDc->SetTextColor (RGB (25500));  
    pDC->DrawText (str, str.GetLength (), rcView, DT_SINGLELINE | DT_CENTER | DT_VCENTER);  
}  
 
51、如何创建一个具有特定点大小的字体  
 
可以指定字体逻辑单位的大小,但有时指定字体的点的大小可能会更方便一些。可以如下将字体的点转换为字体的高度:  
int nHeigth=mulDiv (nPointSize, -dc.GetDeviceCaps (LOGPIXELSY), 72);  
下例创建了一个8点的Apial字体:  
CClientDC dc (AqfxGetMainWnd ());  
m_font. CreateFont (MulDiv (8, -dc.GetDeviceCaps (LOGPIXELSY), 72),0,0,0,FW_NORMAL,0,0,0,ANSI_CHARSET, OUT_STROKE_PRECIS,CLIP_STROKE_PRECIS,DRAFT_QUALITY, VARIABLE_PITCH | FF-SWISS,_T ("Arial"));  
 
52、如何计算一个串的大小  
 
函数CDC:: Det text Extent 根据当前选择的字体计算一个串的高度和宽度。如果使用的不是系统字体而是其他字体,则在调用GetTextExtent之前将字体选进设备上下文中是很重要的,否则计算高度和宽度时将依据系统字体,由此得出的结果当然是不正确的。下述样板程序当改变下压按钮的标题时动态调整按钮的大小,按钮的大小由按钮的字体和标题的大小而定。响应消息WM_SETTEXT时调用OnSetText,该消息使用ON_MESSAE宏指令定义的用户自定义消息。  
 
LRESULT CMyButton:: OnSettext (WPARAM wParam, LPARAM lParam)  
{  
    //Pass message to window procedure.  
    LRESULT bResult=CallWindowProc (*GetSuperWndProcAddr (),  
    m_hWnd, GetCurrentMessage () ->message,wParam,lParam);  
    //Get title of push button.  
    CString strTitle;  
    GetWindowText (strTitle);  
    //Select current font into device context.  
    CDC* pDC=GetDc ();  
    CFont*pFont=GetFont ();  
    CFont*pOldFont=pDC->SelectObject (pFont);  
    //Calculate size of title.  
    CSize size=pDC->GetTextExent (strTitle,strTitle.GetLength ());  
    //Adjust the button's size based on its title.  
    //Add a 5-pixel border around the button.  
    SetWindowPos (NULL, 00, size.cx+10, size.cy+10, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);  
    //Clean up.  
    pDC->SelectFont (pOldFont);  
    ReleaseDC (pDC);  
    return bResult;  
}  
 
53、如何显示旋转文本  
 
只要用户使用TrueType或者GDI笔或字体就可以显示旋转文本(有些硬件设备也支持旋转光栅字体)。LOGFONT结构中的ifEscapement成员指定了文本行和x轴的角度,角度的单位是十分之一度而不是度,例如,ifEscapement为450表示字体旋转45度。为确保所有的字体沿坐标系统的同一方向旋转,一定要设置ifEscapement成员的CLIP_LH_ANGLES位,否则,有些字体可能反向旋转。下例使用了14点Arial字体每间隔15度画一个串。  
 
void CSampleView:: OnDraw (CDC* pDC)  
{  
    //Determine the size of the window.  
    CRect rcClient;  
    GetClientRect (rcClient);  
    //Create sample string.  
    CString str (_T ("Wheeee...I am rotating!"));  
    //Draw transparent, red text.  
    pDC->SetBkMode (TRANSPARENT);  
    pDC->SetTextColor (RGB (255,0,0));  
    CFont font; //font object  
    LOGFONT stFont; //font definition  
    //Set font attributes that will not change.  
    memset (&stFont, 0sizeof (LOGFONT));  
    stFont.ifheight=MulDiv (14, -pDC->GetDeviceCaps (LOGPIXELSY), 72);  
    stFont.ifWeight=FW_NORMAL;  
    stFont.ifClipPrecision=LCIP_LH_ANGLES;  
    strcpy (stFont.lfFaceName, "Arial");  
    //Draw text at 15degree intervals.  
    for (int nAngle=0; nAngle<3600; nAngle+=150)  
    {  
        //Specify new angle.  
        stFont.lfEscapement=nAngle;  
        //Create and select font into dc.  
        font.CreateFontIndirect (&stfont);  
        CFont* pOldFont=pDC->SelectObject (&font);  
        //Draw the text.  
        pDC->SelectObject (pOldFont);  
        font.DelectObjext ();  
    }  
}  
 
54、如何正确显示包含标签字符的串  
 
调用GDI文本绘画函数时需要展开标签字符,这可以通过调用CDC:: TabbedTextOut或者CDC:: DrawText并指定DT_EXPANDTABS标志来完成。TabbedTextOut函数允许指定标签位的数组,下例指定每20设备单位展开一个标签:  
 
void CSampleView:: OnDraw (CDC* pDC)  
{  
    CTestDoc* pDoc=GetDocument ();  
    ASSERT_VALID (pDoC);  
    CString str;  
    str.Format (_T ("Cathy/tNorman/tOliver"));  
    int nTabStop=20//tabs are every 20 pixels  
    pDC->TabbedtextOut (1010, str, 1, &nTabStop, 10);  
}  
 
55、串太长时如何在其末尾显示一个省略号  
 
调用CDC:: DrawText并指定DT_END_ELLIPSIS标志,这样就可以用小略号取代串末尾的字符使其适合于指定的边界矩形。如果要显示路径信息,指定DT_END_ELLIPSIS标志并省略号取代串中间的字符。  
 
void CSampleView:: OnDraw (CDC* pDC)  
{  
    CTestDoc* pDoc=GetDocument ();  
    ASSERT_VALID (pDoc);  
    //Add ellpsis to end of string if it does not fit  
    pDC->Drawtext (CString ("This is a long string"),  
    CRect (10108030), DT_LEFT | DT_END_ELLIPSIS);  
    //Add ellpsis to middle of string if it does not fit  
    pDC->DrawText (AfxgetApp () ->m_pszhelpfilePath, CRect (104020060), DT_LEFT | DT_PATH_ELLIPSIS);  
}  
 
56、如何快速地格式化一个CString对象  
 
调用CString:: Format,该函数和printf函数具有相同的参数,下例说明了如何使用Format函数:  
 
//Get size of window.  
 
CRect rcWindow;  
GetWindowRect (rcWindow);  
//Format message string.  
CString strMessage;  
strMessage.Format (_T ("Window Size (%d, %d)"), rcWindow.Width (), rcWindow.Height ());  
//Display the message.  
MessageBox (strmessage);  
 

57、为什么即使调用EnableMenuItem菜单项后,菜单项还处于禁止状态  
 
需要将CFrameWnd:: m_bAutomenuEnable设置为FALSE,如果该数据成员为TRUE(缺省值),工作框将自动地禁止没有ON_UPDATE_COMMAND_UI或者ON_COMMAND的菜单项。  
 
//Disable MFC from automatically disabling menu items.  
m_bAuoMenuEnable=FALSE;  
//Now enable the menu item.  
CMenu* pMenu=GetMenu ();  
ASSERT_VALID (pMenu);  
pMenu->EnableMenuItem (ID_MENU_ITEM,MF_BYCOMMAND | MF_ENABLED);  
 
58、如何给系统菜单添加一个菜单项  
 
给系统菜单添加一个菜单项需要进行下述三个步骤:  
首先,使用Resource Symbols对话(在View菜单中选择Resource Symbols... 可以显示该对话)定义菜单项ID,该ID应大于0x0F而小于0xF000;  
其次,调用CWnd::GetSystemMenu获取系统菜单的指针并调用CWnd:: Appendmenu将菜单项添加到菜单中。下例给系统菜单添加两个新的菜单项:  
 
int CMainFrame:: OnCreate (LPCREATESTRUCT lpCreateStruct)  
{  
    …  
    //Make sure system menu item is in the right range.  
    ASSERT (IDM_MYSYSITEM &0xFFF0)==IDM_MYSYSITEM);  
    ASSERT (IDM-MYSYSITEM<0xF000);  
    //Get pointer to system menu.  
    CMenu* pSysmenu=GetSystemmenu (FALSE);  
    ASSERT_VALID (pSysMenu);  
    //Add a separator and our menu item to system menu.  
    CString StrMenuItem (_T ("New menu item"));  
    pSysMenu->Appendmenu (MF_SEPARATOR);  
    pSysMenu->AppendMenu (MF_STRING, IDM_MYSYSITEM, strMenuitem);  
    …  
}  
 
现在,选择系统菜单项时用户应进行检测。使用ClassWizard处理WM_SYSCOMMAND消息并检测用户菜单的nID参数:  
 
void CMainFrame:: OnSysCommand (UINT nID,LPARAM lParam)  
{  
    //Determine if our system menu item was selected.  
    if ( (nID & 0xFFF0)==IDM_MYSYSITEM)  
    {  
        //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, 00)==0)  
    {  
        ++nCount;  
    }  
        hWnd=:: GetWindow (hWnd, GW_HWNDNEXT);  
    }  
    …  
}  
 

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" ) ;  
}  
 
请问有谁知道是什么原因?谁在DLL中做过类似工作,望赐教。ror”, 我记得AfxRegisterWndClass好象应该在PreCreateWindow中调用,  
在构造函数中用这个函数似乎有问题,你再试试吧! 用C++作DLL可以吗?好象名字分裂回有些负作用吧?  
用MFC C++是可以做传统的DLL的。只要将回调函数定义成如下格式就行了:  
#ifdef __cplusplus  
extern "C" {  
#endif  
void __export FAR PASCAL fun() ;  
#ifdef __cplusplus  
}  
#endif  
 
其它与普通MFC程序一样。当然,在例程类的定义上也有点特别的地方 我如果在正常的执行程序中这样用CreateEx就没有任何问题,而在DLL中 就有问题。并且这问题也只发生在WIN3.1上,在WIN95上却可以正常执行。  
-  
 
75.如何让TOOLTIP的字体变大  
 
前几天有个虫虫问如何让vc4.0的Tooltip的字体变大,可现在文章没有了.不过现在我有个方法:在Windows 95 Desktop 属性中有desktop scheme中有Tooltip一项,可以该变 TOOLTIP的字体和大小.不过这样做所有程序的Tooltip都变大了.这可能不是你的本意. 但Tooltip是Windows 95 Common Control,由Windows 95内部实现,VC4.0的CTooltip类并不实现Tips的显示,所以要实现针对某个程序的 Tooltip的特殊显示,有一定难度.我以前曾经试图实现Tooltip的多行显示,做到了当Toolt. 显示时触发我的函数,消失时触发我的函数,但在显示时却出GP错误.现在我认为最简单的方法是从头自己实现Tooltip类.一切随心所欲

阅读(802) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~