学习笔记总结(VC)

总结这段时间科研过程中的学习到的一些知识和小技巧。

1。关于SendMessage发送CString的问题

方法1:

Send: CString *str = new CString ("aaa");

               hwnd->SendMessage(WM_USER,0,(LPARAM)str);

Recv:   void myproc(.......)  //自定义消息处理函数

{          CString *pstr = (CString*)lparam;

            .......

            delete pstr; //注意此处要删除前面send处new出来的CString      }

方法2:

CString s="aaa";

hwnd->SendMessage(WM_USER,0,(LPARAM)(LPCTSTR)s);

Recv:   void myproc(.......)  //自定义消息处理函数

{  LPCTSTR pstr=(LPCTSTR)lparam;

................        }

2。查找窗口FindWindow( a, b)

a 窗口类名,根据跟踪看,VC中用“#32770”代替此参数,即可查找出所有弹出的窗口,一般情况下可作NULL。

b 窗口标题,正常查找某一个窗口,即可用此参数作唯一标识。

3。CEdit滑块根据内容自动滚动

UpdateData(FALSE);         //注意更新控件

m_edit.LineScroll(m_edit.GetLineCount( ),0 );   //参数一是行数,参数二是该行的字符位置;

注意:edit控件要设为multiline属性。

用此方法,即可保证在输入多行字符后,edit控件能自动滚动至最后一行。

要滚动CEdit,   下面几种办法都可以:  
  m_edit.SendMessage(   WM_VSCROLL,   SB_LINEDOWN,   0   );  
  m_edit.LineScroll(   3,   3   );  
  ::SendMessage(m_edit.m_hWnd,EM_LINESCROLL,3,12);     
    
  简单的方法,让字符在指定的行数显示:  
  int   index   =   m_edit.LineIndex(   5   );  
  m_edit.SetSel(   index,   index   );  
  m_edit.ReplaceSel(   "dir"   );

4。判断程序是否已启动

方法 1:

CYourApp::InitInstance()

{ CreateMutex(   NULL,   FALSE,   "Application   Mutex"   );//   添加互斥量 ,参数3自定义即可  
    
 if(GetLastError()==ERROR_ALREADY_EXISTS)  
 {  
  AfxMessageBox("程序以运行!");  
  return   FALSE;  
 } }

方法 2 :查找到以后,激活程序到前台,但FindWindow过程中,如果有同名的文件夹,而程序没启,文件夹窗口会被激活-_-||  方法有些小问题待改进。

CYourApp::InitInstance()

{ CString  strCaption;  
 strCaption.LoadString(AFX_IDS_APP_TITLE);  
 CWnd* pwndFirst = CWnd::FindWindow(NULL, strCaption);  
 if (pwndFirst)  
 {  
  //   another   instance   is   already   running   -   activate   it  
  CWnd* pwndPopup = pwndFirst->GetLastActivePopup();  
  pwndFirst->SetForegroundWindow();  
  pwndFirst->ShowWindow(SW_SHOWNORMAL);  
  if(pwndFirst != pwndPopup)  
   pwndPopup->SetForegroundWindow();  
  return FALSE;  
 } }

5。CTreeCtrl传递参数问题

插入树中的TVINSERTSTRUCT结构有参数,可通过lparam传递,也可通过SetItemData设置,并通过GetItemData获取。

注意:传递的参数是指针值,所以要注意原始传递的参数的有效期,否则传递过去的即可能不存在而消失。

          参数可以是普通的CString,也可以是结构指针。

     TVINSERTSTRUCT tvInsert;
     tvInsert.hParent = hParent;
     tvInsert.hInsertAfter = NULL;
     tvInsert.item.iImage = 0;
     tvInsert.item.iSelectedImage = 0;
     tvInsert.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT | TVIF_PARAM;
     tvInsert.item.pszText = (LPTSTR)(LPCTSTR)ph.Name; //标题
     //tvInsert.item.lParam = (LPARAM)(LPCTSTR)ph.Num;  //指针传值
    
     HTREEITEM hSub = m_Infotree.InsertItem(&tvInsert); 
     m_Infotree.SetItemData(hSub2,(DWORD)(LPCTSTR)ph.Num);  //设置该树枝的参数供传递

在onselchange事件中处理参数:

void CTabDlg0::OnSelchangedInfotree(NMHDR* pNMHDR, LRESULT* pResult)
{
 NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
 // TODO: Add your control notification handler code here
 
 /* 获取TVITEM的lparam参数值
 LPCTSTR str=(LPCTSTR)pNMTreeView->itemNew.lParam;
  if(CString(str)!="")
     AfxMessageBox(CString(str));*/
    
 //获取设置的itemData方法,也可在程序其他部分调用该部分获取传递参数

 HTREEITEM hSelected = pNMTreeView->itemNew.hItem;
 LPCTSTR str = (LPCTSTR)m_Infotree.GetItemData(hSelected);
        
 *pResult = 0;
}

6。CTreeCtrl遍历循环方法(参考)

 void Tree{

HTREEITEM hitem=NULL;
 CString str;
 hitem=m_Infotree.GetRootItem();    //取得根节点
 while(hitem)
 {
  //str=m_Infotree.GetItemText (hitem);

  Traversal(hitem);
  hitem=m_Infotree.GetNextSiblingItem (hitem); //取得指定节点hitem的下一个兄弟节点
 }

}

void Traversal(HTREEITEM hitem)    //函数Traversal( )采用递归方法遍历指定节点hitem的所有子节点
{
    HTREEITEM hnext;
    CString str;
    hnext=m_Infotree.GetChildItem(hitem);    //取得指定节点hitem的子节点
    while(hnext)
 { 
//str=m_Infotree.GetItemText (hnext);        

        Traversal(hnext);
        hnext=m_Infotree.GetNextSiblingItem(hnext);  //GetPrevSiblingItem( )取兄弟节点的上一节点
    }
}

 
原文地址:https://www.cnblogs.com/rainbowzc/p/2422164.html