所学7

本文介绍了MFC编程中DLL初始化的问题、多线程锁的正确使用方法、消息过滤函数的注意事项等,同时还涉及了逻辑右移与算术右移的区别、控件定位的重要性、虚拟列表的使用场景、多态的正确运用、友元函数的作用、回调函数的设计原则、抽象工厂模式的应用、SQLite3表字段修改的方法以及如何根据进程句柄查找进程路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.DLL的InitInstance和ExitInstance不会执行
Settings->C/C++->Preprocessor->Preprocessor Definitions->少了一个_USRDLL
_USRDLL是编译宏选项,MFC Library支持两种类型的DLL:_USRDLL 和_AFXDLL._USRDLL 模式需要CWinApp对象来执行dll使用的MFC Library窗口的初始化和清除.而_AFXDLL不需要CWinApp对象,因为他与使用他的应用程序共享MFC Library,他不需要CWinApp提供初始化和清除工作

2.为避免死锁,请对所有多重加锁的语句都按照相同顺序加锁。比如
Thread1:
lock A
lock B
unlock B
unlock A
Thread2:
不要
lock B
lock A
unlock A
unlock B
而要
lock A
lock B
unlock B
unlock A

3.消息过滤函数返回值不能瞎写,return 0 的话可能连窗体都创建不出来,你还找不到错误!
血的教训

E:/cary/主线/trunk/app/PayAssistant新/PayAssistant/Debug/image/pay_cancel_normal.bmp

4.>>>,称为逻辑右移,右移n位,空位补0。>>称为算术右移,右移n位,空位用原最高位的位值补足,相当于E/2n,能保留原数的符号

5.好多是否忘记了加;是因为函数名没有解析成功当成字符串了   看看是否遗漏了添加什么头文件

6.血的教训   mfc控件千万别摆在哪就认为他在哪  一定要自己去将他的位置固定住!否则在不同的系统中,控件的位置有所不同

7.虚拟列表(virtual list control) 可以解决上万条数据插入的时候比较缓慢   http://blog.youkuaiyun.com/denglei265/article/details/15335169

8.多态运用  在使用多态时,在new和delete时一定要保持原有对象类型,不能在new时就进行强制转换,否则会在析构时出现问题
  CInherit *p_cb=new CInherit();
   ((CBase*)p_cb)->call();
   delete p_cb;
但运用时可以将基类析构函数写成虚函数,这样delete就会走子类的析构了

9.有元函数  
设置成有元函数和类 就可以访问其类中各种权限的何种资源
  class A
       {
              …
       public:
              friend class B;
              …
       };
       经过以上说明后,类B的所有成员函数都是类A的友元函数,能存取类A的私有成员和保护成员。

10.为什么不要轻易在.h中写实现,注意:如果在预编译中引用了这个.h,或者这个.h是大家都用的    另外两个.h互相引用了 ,就会出现重定义的情况!!所以声明和定义要分开写这样是最理想的,除非你能保证不会重复引用造成重定义!

11.回调函数为什么一定要是全局或者类的静态函数呢?

在使用STL算法时,如:sort函数的第三个参数

template<classRandomAccessIterator, class Predicate>

   void sort(

      RandomAccessIterator _First,

      RandomAccessIterator _Last,

      Predicate _Comp

  );

Predicate是个函数指针

当我们调用sort时,_Comp会被windows调用,但是windows并不借助任何函数来调用它,所以windows要先知道该函数的地址,
有两种方式
1. 全局函数
2.静态的类函数
回调函数一般都需要this指针来置顶

12.抽象工厂用的也多,状态模式也常用,命令模式也挺常见

13.Sqlite3 修改表字段功能函数
BOOL CInvoiceInfoTable::ChangeRowNature()
{
    //先将表重命名
    char achsql[MAX_PATH]={0};
    Safe_sprintf(achsql,sizeof(achsql),"ALTER TABLE ClassStruct RENAME TO ClassStruct2008");
    string sTemp;
    if (!ExecuteSql(sTemp))
    {
        GEILOG("ExecuteSql false");
        return FALSE;
    }
    
    //重新创建表
    Safe_sprintf(achsql,sizeof(achsql),"CREATE TABLE IF NOT EXISTS ClassStruct('Name' TEXT, 'Class' TEXT);");
    string sTemp;
    if (!ExecuteSql(sTemp))
    {
        GEILOG("ExecuteSql false");
        return FALSE;
    }

    Safe_sprintf(achsql,sizeof(achsql),"INSERT INTO  ClassStruct(Name,Class)SELECT (Name,Class) FROM ClassStruct2008");
    string sTemp;
    if (!ExecuteSql(sTemp))
    {
        GEILOG("ExecuteSql false");
        return FALSE;
    }

    Safe_sprintf(achsql,sizeof(achsql),"DROP TABLE ClassStruct2008");
    string sTemp;
    if (!ExecuteSql(sTemp))
    {
        GEILOG("ExecuteSql false");
        return FALSE;
    }
    
}



13.根据进程句柄查找进程路径
void GetProcessFilePath(IN HANDLE hProcess, OUT CString& sFilePath)
    {
    sFilePath = _T("");
    TCHAR tsFileDosPath[MAX_PATH + 1];
    ZeroMemory(tsFileDosPath, sizeof(TCHAR)*(MAX_PATH + 1));
    if (0 == GetProcessImageFileName(hProcess, tsFileDosPath, MAX_PATH + 1))
        {
        return;
        }

    // 获取Logic Drive String长度
    UINT uiLen = GetLogicalDriveStrings(0, NULL);
    if (0 == uiLen)
        {
        return;
        }

    PTSTR pLogicDriveString = new TCHAR[uiLen + 1];
    ZeroMemory(pLogicDriveString, uiLen + 1);
    uiLen = GetLogicalDriveStrings(uiLen, pLogicDriveString);
    if (0 == uiLen)
        {
        delete[]pLogicDriveString;
        return;
        }

    TCHAR szDrive[3] = TEXT(" :");
    PTSTR pDosDriveName = new TCHAR[MAX_PATH];
    PTSTR pLogicIndex = pLogicDriveString;

    do
        {
        szDrive[0] = *pLogicIndex;
        uiLen = QueryDosDevice(szDrive, pDosDriveName, MAX_PATH);
        if (0 == uiLen)
            {
            if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
                {
                break;
                }

            delete[]pDosDriveName;
            pDosDriveName = new TCHAR[uiLen + 1];
            uiLen = QueryDosDevice(szDrive, pDosDriveName, uiLen + 1);
            if (0 == uiLen)
                {
                break;
                }
            }

        uiLen = _tcslen(pDosDriveName);
        if (0 == _tcsnicmp(tsFileDosPath, pDosDriveName, uiLen))
            {
            sFilePath.Format(_T("%s%s"), szDrive, tsFileDosPath + uiLen);
            break;
            }

        while (*pLogicIndex++);
        } while (*pLogicIndex);

        delete[]pLogicDriveString;
        delete[]pDosDriveName;
    }




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值