MFC函数随看随记

    POINT pt;
    GetCursorPos(&pt);// 该函数检取光标的位置,以屏幕坐标表示
    UINT uFlags;
    ScreenToClient(&pt);  // 该函数把 屏幕 上指定点的屏幕 坐标转换 成用户坐标。

    MapWindowPoints(this, &pt,1);//该函数把相对于一个窗口的坐标空间一组点映射成相对于另一窗口的坐标空间的一组点

   HTREEITEM hItem = HitTest(pt,&uFlags);//CTreeCtrl::HitTest 回位于指定点的treeview项的句柄,如果没有项位于该点,则返回NULL。

 //pFlags指向一个用来接收有关点击测试的信息的整数的指针。它可以是说明部分中列出的flags成员值中的一个或多个。

   //P此成员函数用来确定相对于一个treeview控件的客户区的指定点的定位。

    CMenu menu;
    menu.LoadMenu(IDR_MENU_DEVICETREE);//加载id为XXX的菜单俩个参数:1默认为this,可指定窗口。2资源id。

    menu.GetSubMenu(0)->DeleteMenu(ID_DEVICETREE_ADDCAM, MF_BYCOMMAND);//1:该函数取得被指定菜单激活的下拉式菜单或子菜单的句柄。2:删除id为XXX的菜单项


deletemenu和removemenu的区别

1.The DeleteMenu function destroys the handle to the menu or submenu and frees the memory used by the menu or submenu. 
它使菜单或者子菜单的handle无效(destroys)。
2. RemoveMenu does not destroy the menu or its handle, allowing the menu to be reused.可以再利用,并不从内存中将menu删除。


menu.GetSubMenu(0)->ModifyMenu(ID_DEVICETREE_EXPAND, MF_BYCOMMAND, ID_DEVICETREE_EXPAND, "收拢");//该参数修改已存在的菜单项,并指定菜单项的内容、外观和性能。


menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, this);//该函数在指定位置显示快捷菜单,并跟踪菜单项的选择。


HTREEITEM hSelNode = GetSelectedItem();//获取当前选中的item


SetItemData:是将各项的序号和自己需要的内容相关联,这个内容是自己定义的任何类型的东西,如果是一个结构体或是一个类对像,则要将其转换为指针类型即可.

GetItemData:是将关联的内容取出来

 

例如:

    int mydata=1000;

    CComboBox bobox;

    int index=bobox.AddString("sfdsaf");  //增加一个项

    bobox.SetItemData(index,mydata);     //将index项关联上自已的变量,可能以后要用于绘制颜色等.

    int myreturndata=bobox.GetItemData(index);  //取出关联的值,此时myreturndata应该为1000;


    pDeviceInfo->node = InsertItem(strDevName.c_str(), pDeviceInfo->devImage, pDeviceInfo->devImage);
        InsertItem(pDeviceInfo->dev.cam.camName, ICON_CAMERA_INIT, ICON_CAMERA_INIT, pDeviceInfo->node);
        SetItemData(pDeviceInfo->node, (DWORD_PTR)pDeviceInfo);//关联

    DeviceInfo *  pDeviceInfo = (DeviceInfo *)(GetItemData(GetParentItem(hSelNode)));//获取关联数据


CWnd * pMainWnd = AfxGetApp()->GetMainWnd();//获取主窗口句柄

pMainWnd->SendMessage(WM_PLAY_OR_STOP, (WPARAM)&playingInfo, (LPARAM)playingWinIdx);//给主窗口发消息


CView * pActiveView = GetActiveView();//我的实例中该函数应该是获取view窗口


CComboBox::GetCount()//返回 combox内对象数目

list::clear()//清空list

::erase()//从指定容器删除指定位置的元素或某段范围内的元素


(CButton *)GetDlgItem(IDC_BUTTON_SEARCH)->EnableWindow(FALSE);//使button无效


while(hRootNode != NULL)
    {
        if (m_bNodeExpand)
        {
            Expand(hRootNode, TVE_EXPAND);
        }
        else
        {
            Expand(hRootNode, TVE_COLLAPSE);
        }


        hRootNode = GetNextItem(hRootNode, TVGN_NEXT);
    }//treectrl展开和收起


=======================================================================================================================

CLASS_DECLARE()
    PROPERTY_DECLARE(ExamInfo, int, examInfoID)
    PROPERTY_DECLARE(ExamInfo, int, studentID) 
    PROPERTY_DECLARE(ExamInfo, int, obejctType)//考试科目 
    PROPERTY_DECLARE(ExamInfo, int, carID)
    PROPERTY_DECLARE(ExamInfo, int, placeID)
    PROPERTY_DECLARE(ExamInfo, int, examStatus)//考试状态,enumExamStatus取值,数据库中只保存“未考试”和“考试完成”两种状态

成员(member_name)在类(typen_ame)中的偏移:
    
    (int)(&((type_name*)NULL)->member_name)
    
    例如有个类 A
    
    class A
    
    {
    
    public:
    
    virtual int show() {}
    
    int i1, i2;
    
    };
    
    则 (int)(&((A*)NULL)->i2) == 8
    
    类地址+8的偏移处为i2的地址(4字节vmt表地址,4字节i1,所以i2的寻址偏移为8)
    
    这样就能在属性类中自己计算出拥有属性类的类的地址了,这是因为类的寻址方式决定的,如下所示:
    
    class Child
    
    {
    
    public:
    
    int i1, i2; i1偏移为0, i2为4,无vmt表
    
    };
    
    class Parent
    
    {
    
    public:
    
    int i; i偏移为0
    
    Child *c; c偏移为4
    
    Parnet() {…} c的new 和 delete就不写了
    
    };
    
    Parent *p;
    
    这时要new一个Parent类时,会在堆上分配二块内存,一块为c对象占用内存,一块为p对象占用内存。
    
    要寻址类P对象中c对象的i2成员(p->c->i2),大概的汇编代码如下:
    
    mov ecx, p //得到p的指针
    
    mov ecx, [ecx + 4] //得到p对象成员c的指针
    
    mov eax, [ecx + 4] //得到c对象成员i2的地址
    
    这样就寻址到了i2
    
    但如果Parent类不是包含的Child类的指针,而是直接包含的对象,情况就不一样了,如下:
    
    class Parent
    
    {
    
    public:
    
    int i; i偏移为0
    
    Child c; c偏移为4(注意不同,这里c不是Child*了)
    
    };
    
    Parent *p;
    
    这时要new一个Parent类时,只会在堆上分配一块内存,为p对象占用内存,c对象包含在p对象内,直接使用p对象的内存,要寻址类P对象中c对象的i2成员(p->c.i2),大概的汇编代码如下:
    
    mov ecx, p //得到p的指针
    
    mov ecx, ecx + 8 //得到i2的地址 8 = c偏移+i2在c类中的偏移,编译优化
    
    要寻址类P对象中c对象的地址,如下:
    
    mov ecx, p //得到p的指针
    
    mov ecx, ecx + 4 //得到c的地址 p对象指针+偏移
    
    从上面可以看出,只要知道c类地址,要得到p的指针,就 c地址 - c对象在p对象中的偏移就行了。
    
    事情就简单了,示例代码如下:
    
    #include <iostream>
    
    using std::cout;
    
    using std::cin;
    
    using std::endl;
    
    template<typename T, typename int(*GetOffset)()>
    
    class Property
    
    {
    
    public:
    
    Property()
    
    {
    
    cout 《 “this:” 《 (int)this 《 std::endl;
    
    cout 《 “owner:” 《 (int)this - GetOffset() 《 std::endl;
    
    }
    
    };
    
    #define PROPERTY_DECLARE(pro_name, type_name)/
    
    private: int inline static pro_name##_offset() {return (int)(&((type_name*)NULL)->pro_name);};/
    
    public: Property<type_name, type_name::pro_name##_offset> pro_name;
    
    class PropertyTest
    
    {
    
    public:
    
    int i;
    
    public:
    
    PROPERTY_DECLARE(Name, PropertyTest)
    
    };
    
    int main()
    
    {
    
    PropertyTest *test = new PropertyTest();
    
    cout 《 std::endl;
    
    cout 《 “property address:” 《 (int)(&test->Name) 《 std::endl;
    
    cout 《 “test class address:” 《 (int)test 《 std::endl;
    
    std::cin.get();
    
    return 0;
    
    }

子窗口给主窗口发送信息,需要主窗口重写OnWndMsg()


子窗口的某一个事件中调    AfxGetApp()->GetMainWnd()->SendMessage(0x10001);

主窗口内重写  virtual BOOL OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult);

实现部分

BOOL CMy08191419treetestDlg::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
UINT p = message;
switch(p)
{
case 0x10001:
::MessageBoxA(NULL,"XXX","XXX",MB_OK);
break;
default:
break;
}
return CDialogEx::OnWndMsg(message, wParam, lParam, pResult);
}

窗口大小发生改变时,想要调整窗口内控件位置  需要重写onsize()函数

afx_msg void OnSize(UINT nType, int cx, int cy);


实现:

void CMy08191419treetestDlg::OnSize(UINT nType, int cx, int cy)
{
CDialogEx::OnSize(nType, cx, cy);
//::MessageBoxA(NULL,"asd","ads",MB_OK);
if(nType == SIZE_MAXIMIZED )
{
m_tab.MoveWindow(0,0,cx,cy);
}
}

别忘记在消息映射中添加ON_WM_SIZE()否则会没反应





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值