两个很奇怪的内存泄露·附代码,请帮忙看看·我是新手,谢谢!泄露全部是用BoundsChecker 7.2检查出来的。★① 问题出在动态更改背景色上
COLORREF crBColor = CIniFile::ReadInteger(TEXT("HEALTH-OPTION"), TEXT("BackgroundColor"), 16777215);
SetClassLong(g_hWnd, GCL_HBRBACKGROUND, (long)CreateSolidBrush(crBColor));
提示:
Type Quantity Deallocator Allocation Location SequenceCreateSolidBrush 2 DeleteObject PreLockWindow - [UserFunction.h, line 618 (***.exe)]
★② 问题出在HOOK键盘上
extern "C" DLLEXPORT BOOL EnableKeyboardHook(BOOL bEnable)
{
if (bEnable)
{
g_hhkKeyboard = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)KeyHookProc, g_hInstance, 0);
if (!g_hhkKeyboard) return FALSE;
}
else
{
// 启用任务键
if (g_hhkKeyboard)
{
UnhookWindowsHookEx(g_hhkKeyboard);
g_hhkKeyboard = NULL;
}
else
{
return FALSE;
}
}
return TRUE;
}
上面的这个函数,提示泄露原因:UnhookWindowsHookEx
可,我明明有对应的UnhookWindowsHookEx啊。分不多了,请见谅!恳请明白人指点...

解决方案 »

  1.   

    ReadInteger(TEXT("HEALTH-OPTION"), TEXT("BackgroundColor")
    使用参数代进去,不要用字符串值,可能不会立即释放
    第二个暂不清楚
      

  2.   

    第一个 CreateSolidBrush 用完之后, 需要有 DeleteObject 删除创建的 Brush
      

  3.   

    第二个没看出什么问题, 要不你把 if (g_hhkKeyboard) 这个判断去掉试试 ?
      

  4.   

    多谢二位帮忙!
    To Elysium:“使用参数代进去,不要用字符串值,可能不会立即释放”,我没看懂这句话,真抱歉,是指改写成这样吗?
    SetClassLong(g_hWnd, GCL_HBRBACKGROUND, (long)CreateSolidBrush(CIniFile::ReadInteger(TEXT("HEALTH-OPTION"), TEXT("BackgroundColor"), 16777215)));To sgnaw: CreateSolidBrush 之后确实要DeleteObject,可是,我如果写成这样,就无法成功的更改背景色了。
    HBRUSH hbr = CreateSolidBrush(crBColor);
    SetClassLong(g_hWnd, GCL_HBRBACKGROUND, (long)hbr);
    DeleteObject(hbr);
      

  5.   

    我是说声明CString类的变量给ReadInteger
    CString strSection,strValue
    奇怪你这个类不是vc自带的吧,这个函数msdn找不到?可是我怎么看着这么眼熟啊
    Delphi里转过来的?
      

  6.   

    这个类是用SDK自己写的。
    我如果这样:
    HBRUSH hbr = CreateSolidBrush(crBColor);
    SetClassLong(g_hWnd, GCL_HBRBACKGROUND, (long)hbr);
    DeleteObject(hbr);
    虽然不存在资源泄露的问题,可是,无法更改背景色。为何这样就无法更改背景色呢?奇怪。
      

  7.   

    1.改成这样
    HBRUSH hBrush = CreateSolidBrush(crBColor);
    SetClassLong(g_hWnd, GCL_HBRBACKGROUND, (long)hBrush);
    ...
    DeleteObject(hBrush); // 用完后删除2.即使你写了unhook代码,但这段代码是不可能进去的,你想想吧.
    UnhookWindowsHookEx(g_hhkKeyboard);
      

  8.   

    SetClassLong后,调用UpdateWindow刷新一下窗口.
      

  9.   

    如果不想立即 DeleteObject 那就用个变量保存起来, 晚些时候再执行啊.
      

  10.   

    这个类是用SDK自己写的。
    我如果这样:
    HBRUSH hbr = CreateSolidBrush(crBColor);
    SetClassLong(g_hWnd, GCL_HBRBACKGROUND, (long)hbr);
    DeleteObject(hbr);? 
    1.改成这样
    HBRUSH hBrush = CreateSolidBrush(crBColor);
    SetClassLong(g_hWnd, GCL_HBRBACKGROUND, (long)hBrush);
    ...
    DeleteObject(hBrush); // 用完后删除
    ==========
    有什么区别?偶没看出来
      

  11.   

    HBRUSH hbr = CreateSolidBrush(crBColor);
    SetClassLong(g_hWnd, GCL_HBRBACKGROUND, (long)hbr);
    DeleteObject(hbr);将hbr申明为类的局部变量,类对象初始化时hbr = CreateSolidBrush(crBColor);在销毁时DeleteObject(hbr);
      

  12.   

    To sgnaw:“第二个没看出什么问题, 要不你把 if (g_hhkKeyboard) 这个判断去掉试试”,试过了,依然存在泄露。
      

  13.   

    使用CBrush* SelectObject( CBrush* pBrush );创建一个CBrush实例
    然后使用CBrush::CreateSolidBrush试一下
      

  14.   


    1.改成这样
    HBRUSH hBrush = CreateSolidBrush(crBColor);
    SetClassLong(g_hWnd, GCL_HBRBACKGROUND, (long)hBrush);
    ...
    DeleteObject(hBrush); // 用完后删除
    =======================
    汗,竟然没明白这个省略号意思,
    或者CreateSolidBrush后,选中并应用画刷,用完后删除...直接删除肯定不生效了
      

  15.   

    to yjgx007:
    2.即使你写了unhook代码,但这段代码是不可能进去的,你想想吧.
    UnhookWindowsHookEx(g_hhkKeyboard);是否需要单独写一个Unhook的函数?
    新手,而且是自学编程,请抽空指点一下,十分感谢!!
      

  16.   

    程序逻辑有问题,你看SetWindowsHookEx被包含在if括号中,而unhook被包含在else括号中if (bEnable)
    {
    g_hhkKeyboard = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)KeyHookProc, g_hInstance, 0);
    if (!g_hhkKeyboard) return FALSE;
    }
    else
    {
    ...
    if (g_hhkKeyboard)
      Unhook...
    }
      

  17.   

    不行的。我即使改成:
    if (bEnable)
    {
    g_hhkKeyboard = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)KeyHookProc, g_hInstance, 0);
    }
    else
    {
      Unhook...
    }
    内存泄露的问题也一样存在。
      

  18.   

    你没明白我的意思,else里面的怎么能进得去?
      

  19.   

    可,我刚才试了:就算我新写一个函数,也无法解决。
    如果写到一个作用域里,岂不安装之后立刻就被卸掉了?
    不解。能否指点一下应该如何写。
    我尝试写成:
    case TRUE:
    if (g_hhkKeyboard)
    UnhookWindowsHookEx(g_hhkKeyboard);
    // 安装键盘HOOK
    g_hhkKeyboard = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)KeyHookProc, g_hInstance, 0);
    if (!g_hhkKeyboard)
    return FALSE;
    break;
    case FALSE:
    UnhookWindowsHookEx(g_hhkKeyboard);
    g_hhkKeyboard = NULL;
    break;
    }
    但问题依旧。
      

  20.   

    在dll退出的时候, unhook:BOOL WINAPI DllMain(
      HINSTANCE hinstDLL,  // handle to the DLL module
      DWORD fdwReason,     // reason for calling function
      LPVOID lpvReserved   // reserved  if (fdwReason == DLL_PROCESS_DETACH)
         if (g_hhkKeyboard)
             UnHook...;
    );
      

  21.   

    如果不用dll,就在主程序退出时
    CWinApp::ExitInstance里面做.
      

  22.   

    我写成这样,但问题还是存在。
    BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
    {
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    break;
    case DLL_PROCESS_DETACH:
    if (g_hhkKeyboard)
    {
    UnhookWindowsHookEx(g_hhkKeyboard);
    g_hhkKeyboard = NULL;
    }
    break;
    }
    g_hInstance = (HINSTANCE)hModule;
    return TRUE;
    }
      

  23.   

    错误提示如下:
    Type Quantity Deallocator Allocation Location SequenceSetWindowsHookExA 1 UnhookWindowsHookEx EnableKeyboardHook - [Hook.cpp, line 87 (MiniAssist.dll)] 139
    Resource Leak Exiting Program: Handle 0x00260553 allocated by SetWindowsHookExA.Allocation Call Stack - Thread 9 [0x050C]
    EnableKeyboardHook D:\ycdeng\Mini Assistant\Hook\Hook.cpp 87
    LockWindow D:\ycdeng\Mini Assistant\include/UserFunction.h 645
    WorkSaveDataProc D:\ycdeng\Mini Assistant\include/ThreadProc.h 857
    C:\WINDOWS\system32\kernel32.dll!0x0000b508
      

  24.   

    你是不是在工作线程中做的啊,那就在工作线程结束时unhook
      

  25.   

    -----------------------------------
    ╭═══╮ ╭═══╮ ╭══════╮      
    ╰╮ ╭╯ ╰╮ ╭╯ ╰╮ ╭══╮╰╮     
      ║ ║   ║ ║   ║ ║  ╰╮╰╮    
      ║ ║   ║ ║   ║ ║   ║ ║    
      ║ ║   ║ ║   ║ ║   ║ ║    
      ║ ║   ║ ║   ║ ║  ╭╯╭╯    
      ║ ║   ║ ║   ║ ╰══╯╭╯     
      ║ ║   ║ ║   ║ ╭═══╯      
      ║ ║   ║ ║   ║ ║          
      ║ ║   ║ ║   ║ ║          
      ║ ║   ║ ║   ║ ║          
      ╰╮╰╮ ╭╯╭╯   ║ ║          
       ╰╮╰═╯╭╯   ╭╯ ╰╮         
        ╰═══╯    ╰═══╯     
    IT者-IT开发者的网站--10万篇技术资料--天天更新--每天都有进步--看了别忘了收藏起来啊。
                    www.itzhe.cn  IT者
      

  26.   

    是在线程里检查时间,如果满足某一个条件,则调用函数LockWindow(),在这个函数里,安装HOOK,在另一个函数里UnLockWindow卸载HOOK。
    “就在工作线程结束时unhook”,似乎无法做到啊?十分感谢!!只能加到100分了...
      

  27.   

    安装hook和卸载hook的函数在同一个线程中调用,还是?
      

  28.   

    问题解决了,十分感谢yjgx007!!
      

  29.   

    楼主的BoundsChecker 7.2是在哪儿下载的啊,我正需要呢,给个链接啊。发mail也好,多谢了
    [email protected]