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

📄 vc小知识总结(续).txt

📁 一些学C的忠告以及有小程序可学习。应该是终生受用的。
💻 TXT
📖 第 1 页 / 共 5 页
字号:
      if (!AfxInitExtensionModule(extensionDLL, hInstance))
         return false;
      }

   return(true);
}
然后,每次使用DLL资源时,你必须改变资源的句柄,使其指向DLL,并保存exe的资源,以便以后正确恢复

void get_DLL_resource(void)
{
   /* this function changes the resource handle to that of the DLL */
   //这个函数改变资源句柄使其指向DLL
   if (resource_counter == 0)
      {
      save_hInstance = AfxGetResourceHandle();
      AfxSetResourceHandle(extensionDLL.hModule);
      }

   resource_counter++;
}
接着你需要其它函数来恢复资源句柄

void reset_DLL_resource(void)
{
   /* this function restores the resource handle set by
'get_DLL_resource()' */

   if (resource_counter > 0)
      resource_counter--;

   if (resource_counter == 0)
      AfxSetResourceHandle(save_hInstance);
}
接下来一点非常重要,只要有可能就必须恢复资源句柄,否则,你将会遇到许多问题.原因是可执行文件必须重画工具条等等,比如说,如果用户移动DLL的对话框,如果资源句柄仍然为DLL的资源,程序就崩溃了,我发现最好恢复句柄的时机在对话框的OnInitDialog()中,这时对话框的模板等已经读出了.

(44)想隐藏用户界面怎么办?


我编了一个小巧而有趣的工具,当用户使用时我不想让它显示出任何用户界面。听听各位有办法可将视关闭。

你可以注册一个新的窗口类型,它拥有除了WS_VISBLE属性外的任何属性,类似CFrameWnd,在PreCreateWindow方法中实现。另外,你能在OnCreate方法中通过设置m_nCmdShow为SW_HIDE来实现,具体方法如下:

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
        return -1;

    // hide our app
    AfxGetApp()->m_nCmdShow = SW_HIDE;

    return 0;
}


(45)如何实现SDI与MDI的转换?


我想将一个编好的SDI应用程序转换为MDI,很明显要有多处的改变。

你可以这样做:建立一个继承于CMDIChidWnd的类,不防设为CChldFrm.在CWinApp中作如下变化。


InitInstance()
{
. ...
    //instead of adding CSingleDocTemplate
    // Add CMultiDocTemplate.
    pDocTemplate = new CMultiDocTemplate(
           IDR_MAINFRAME,
           RUNTIME_CLASS(CSDIDoc),
           RUNTIME_CLASS(CChldFrm),
// For Main MDI Frame change this frame window from
// CFrameWnd derivative ( i.e. CMainFrame )
// to your CMDIChildWnd derived CChldFrm.
           RUNTIME_CLASS(CSDIView));
/// After this it is required to create the main frame window
// which will contain all the child windows. Now this window is
// what was initially frame window for SDI.
    CMainFrame* pMainFrame = new CMainFrame;
    if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
            return FALSE;
     m_pMainWnd = pMainFrame;
.....
}

在从CMDIFrameWnd中继承的类CMainFrame代替CFramWnd后,所有的类都将从CMDIFrame继承,而不是CFrameWnd,编译运行后你就会发现程序已经从SDI变换到MDI。
注意:在CMainFram中必须将构造函数从private改为public.否则会出错。
 
 
 2005-6-23 15:06:00           
 
  sunxin     
  
  
  等级:管理员 
  文章:1382
  积分:2932
  注册:2004-7-6
               第 3 楼  
 
 

 

(46) CDC中的竖排文本?


在OnDraw成员函数中我想让文本竖直对齐,但CDC类似乎不支持该处理

方法一:如果你的竖直对齐是指旋转文本的话,下面的代码会对你有帮助:该代码检查一个Check box控制,查看文本是否需要旋转.

// m_pcfYTitle is a CFont* to the selected font.
// m_bTotateYTitle is a bool (==TRUE if rotated)

void CPage1::OnRotateytitle()
{
LOGFONT lgf;
m_pcfYTitle->GetLogFont(&lgf);
m_bRotateYTitle=
        ((CButton*)GetDlgItem(IDC_ROTATEYTITLE))->GetCheck()>0;

// escapement is reckoned clockwise in 1/10ths of a degree:
lgf.lfEscapement=-(m_bRotateYTitle*900);
m_pcfYTitle->DeleteObject();

m_pcfYTitle->CreateFontIndirect(&lgf);
DrawSampleChart();
}
注意如果你从CFontDialog中选择了不同的字体,你应该自己设定LOGFONT的lfEscapement成员.将初始化后的lfEscapement值传到CFontDialog中.

方法二:还有一段代码可参考:

LOGFONT LocalLogFont;

strcpy(LocalLogFont.lfFaceName, TypeFace);

LocalLogFont.lfWeight = fWeight;
LocalLogFont.lfEscapement = Orient;
LocalLogFont.lfOrientation = Orient;

if (MyFont.CreateFontIndirect(&LocalLogFont))
   {
   cMyOldFont = cdc->SelectObject(&MyFont);
   }

(47)如何激活变灰的弹出菜单?


在设计菜单时设定为GRAYED的菜单项,如何在运行时激活它?

请看下面的示例代码:

void CMyView::OnRButtonDown(UINT nFlags, CPoint point)
{
CScrollView::OnRButtonDown(nFlags, point);

CMenu *menu, *popup;
menu = new CMenu();

// load menu from resource file
menu->LoadMenu( IDR_POPUPMENU );
popup = menu->GetSubMenu(0); // item 0 is DUMMY

UINT nEnable;
nEnable = MF_BYCOMMAND|MF_GRAYED;

if( your test )
{
  nEnable = MF_BYCOMMAND|MF_ENABLED;
}

popup->EnableMenuItem( ID_YOUR_ID, nEnable );

//display menu
ClientToScreen(&point);
popup->TrackPopupMenu(
   TPM_LEFTALIGN | TPM_RIGHTBUTTON,
   point.x, point.y, this );
delete menu;
}

(48)线程消息?


如何正确地在线程之间传送消息?

下面的代码将会帮你的忙:

void CThread::OnUserOpen( WPARAM wParm, LPARAM lParm )
{
    UNUSED( wParm ) ;
    UNUSED( lParm ) ;
    AfxMessageBox("User Open", MB_OK|MB_ICONEXCLAMATION);
}

当然,也别忘了以下声明:

class CThread : public CWinThread
{
     DECLARE_DYNCREATE(CThread)
protected:
     CThread(); // protected constructor used by dynamic creation
     afx_msg void OnUserOpen( WPARAM wParm, LPARAM lParm );

(49)TreeCtrl控制的显示速度太慢?


我从CTreeCtrl继承了一个TREE控制类,重载主要是为了改写每个节点的文本.我在 OnPaint函数中写了一些代码,但这严重地影响了TREE控制的滚动速度.

OnPaint函数
1.可见节点,对于GetFirstVisibleItem和GetNextVisibleItem来讲,是:
  a.根节点;b.父节点已展开的节点;因此,"可见"意味着"没有被未展开的父节点隐藏".当节点滚动到客户外时,它对上述两个函数来讲仍是可见的.

2.当TREE的内容改变时,它默认只将变为可见的节点重绘.另外其它已经是可见的节点没有必要重绘,TREE只是滚动DC的位图而已.
上面的意思是不要绘制你不需要看的节点,那会导致速度降低.建议,测试节点矩形是否在客户区,使得只有需要绘制的节点才会被绘制.
void CIndentTree::OnPaint()
{
   CPaintDC dc(this); // device context for painting

   HTREEITEM hItem = NULL;

   DRAWITEMSTRUCT dis;
   CRect rc;

   // redraw only visible items with indentation
   for(
      hItem = GetFirstVisibleItem();
      hItem; hItem = GetNextVisibleItem( hItem ) )
   {
      if( !GetItemRect( hItem, rc, FALSE ) )
         continue;

      if( rc.top <= dc.m_ps.rcPaint.bottom &&
         rc.bottom > dc.m_ps.rcPaint.top &&=20
         rc.left <= dc.m_ps.rcPaint.right &&
         rc.right > dc.m_ps.rcPaint.left )
      {
         dis.hwndItem = (HWND)hItem;
         dis.rcItem = rc;
         OnDrawItem(0, &dis, &dc);
      }
   }
}
OnDrawItem函数
1.删掉如下代码:

      IMAGEINFO* pinfo = new IMAGEINFO;
      ...
      delete pinfo;
没有必要使用动态的IMAGEINFO变量,你可以将其定义为堆栈变量.
2.GetItemState和GetItemText都是使用的GetItem,因此,你只需调用一次, 就可以从节点获得你要的所有信息.

(50)关于工具条?


我需要在程序中做一个FLAT工具条,于是我加入一个变量m_wndToolBar. 在程序主体窗口的OnCreate()函数中修改工具条状态(0,TBSTYLE_FLAT). 在NT中运行正常,为什么在95中工具条变得透明?

在COMCTL32.DLL中的旧版本中有些小bug,绘画时会带来一些问题, 你可以使用一些定制代码,在www.codeguru.com站点上有下载,如果你使用的是6.0版本,你也可以使用下列代码(摘自我的mainfrm.cpp文件)

m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP |
CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
用CreateEx替换ModifyStyle在同一尺寸的工具条中有些不同((CreateEx 建立的略小些),试一下,如果你仍然有这个问题,检查一下COMCTL32.DLL的版本使用标准按钮替换FLAT.

(51)关于线程消息?


真奇怪,OnUserOpen()函数和OnUserOpen(WPARAM, LPARAM)函数竟然不是一个函数,编译器在查到OnUserOpen(WPARAM, LPARAM)时,不会调用OnUserOpen 莫非有人在消息映象做了什么手脚?

其实,这是MFC严密的表现,处理时,通过函数指针来调用,而该指针是由发生的事件所决定的.如果句柄不正确定义的话,调用当然是非法的


(52)关于控件的焦点?


有谁能给我一个有效的方法:当一个控件失去焦点时,怎样管理才能使对话框的焦点进入到正确的控件.

我有一个可运行的程序来实现,不一定很全面,但能工作.

const int WM_VALIDATE_PARAMS WM_APP + 101;

void CMyDlg::OnKillfocusName()
{
    PostMessage(WM_VALIDATE_PARAMS, ED_NAME, 0L);
}

void CMyDlg::OnKillfocusAddress()
{
    PostMessage(WM_VALIDATE_PARAMS, ED_ADDRESS, 0L);
}

bool CMyDlg::OnValidateParams(WPARAM rcId, LPARAM)
{
        switch( rcId )
        {
        case ED_NAME:
        if( !validateName() )
            m_edName.SetFocus();
        break;

        case ED_ADDRESS:
        if( !validateAddress() )
            m_edAddress.SetFocus();
        break;

    default:
        break;
    }

    return true;
}
上面的代码可以在用户使用TAB键或鼠标操纵时,使用焦点跳至下一个控制.当你想DISABLE一个控件或重设焦点时,会有些问题,特别是在Killfocus事件中。

(53)如何捕获键盘按键?


在CTabCtrl的子对话框怎样才能捕获ALT+0组合键

可以在PreTranslateMessage中截取键盘消息。


(54)怎样实现3D效果?


在对话框中怎样实现Edit和Listboxes控件的3D效果?(环境95/NT VC5.0)

1). 使用带WS_EX_CLIENTEDGE标志的::CreateWindowEx来替换::CreateWindow 或者用CWnd::CreateEx替换CWnd::Create.
2).在建立控件之后,调用ModifyStyleEx(0, WS_EX_CLIENTEDGE).


(55)怎样建立客户CSocket?


我有一个客户socket想在socket中建立一个局域联接.我使用下列顺序:

CSocket* m_pSocket;
m_pSocket = new CSMSSocket(this);
m_pSocket->Create();
m_pSocket->Bind(m_intHostPort, m_strHostIPAddress);
m_pSocket->Connect(lpszAddress, nPort);
但每次Windows Socket都定向到别的端口,怎样才能定向到同一个端口(环境:95/NT VC5.0).

1).如果你想用Client Socket,你就不能在connect()之前调用bind(),因为局域端口地址由TCP/IP设置,我们不可能知道下一次将使用那一个端口,我想我们不必这做.
2).看一下Create()的帮助,里面告诉我们必须给Create()指定一个端口值, 缺省的情况为0,也就是由Window为我们选择一个端口,通过Create()将会自动捆绑. 3).我不认为你应该完成所有的工作,但想总是用一个相同的端口来连接远程机器是一个不正确的想法.
问题出在端口数/地址结合必须唯一,如果你想在Create()中指一个固定的端口数,你只能与远程机器建一个单个连接.在你所写的代码中是允许局域端口数可变化,可以打开多个连接来取得相同的地址.在侦听(listening)Socket中有许多理由使用一个固定端口,但在连接(connecting Socket中我想没有太多的必要.

(56)Disable一个非模态对话框的客户区?

⌨️ 快捷键说明

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