作者共发了8篇帖子。 字体大小:较小 - 100% (默认)▼  内容转换:不转换▼
 
点击 回复
386 7
【代码】用一行代码强制删除Listbox的灰色虚线框
一派护法 十九级
1楼 发表于:2015-12-27 18:19
最终效果:无论怎么选择,ListBox都永远不会显示灰色的虚线框。


在响应WM_DRAWITEM消息的函数中,switch (lpDis->itemAction)下响应ODA_FOCUS事件,并在其中执行:DrawFocusRect(lpDis->hDC, &lpDis->rcItem);
其中lpDis->rcItem表示的就是将要出现的选择框的位置的大小。
一派护法 十九级
2楼 发表于:2015-12-27 18:20
最终代码:

其中选中的那行是重点。
一派护法 十九级
3楼 发表于:2015-12-27 23:22
【补充】
ODA_DRAWENTIRE部分采用GDI+双缓冲后的代码:
/*
** Draw the bitmap and text for the list box item.
** Draw a rectangle around the bitmap if it is selected.
**/
void Dlg2_DrawItem(HWND hDlg, LPARAM lParam)
{
    LPDRAWITEMSTRUCT lpDis = (LPDRAWITEMSTRUCT)lParam;
    switch (lpDis->itemAction)
    {
    case ODA_SELECT:
    case ODA_DRAWENTIRE:
        if (lpDis->itemID != -1)
        {
            // Create compatible graphic
            int width = lpDis->rcItem.right - lpDis->rcItem.left;
            int height = lpDis->rcItem.bottom - lpDis->rcItem.top;
            Bitmap bmpMem(width, height);
            Graphics gpMem(&bmpMem);

            // Main Drawing
            int color;
            if (lpDis->itemState & ODS_SELECTED)
                color = COLOR_HIGHLIGHT; // when selected
            else
                color = COLOR_WINDOW; // when not selected
            character.Display(&gpMem, lpDis->itemID, 0, 0, 0, color, ICON_PADDING_H, ICON_PADDING_V);

            // Copy to screen
            Graphics graphics(lpDis->hDC);
            graphics.DrawImage(&bmpMem, lpDis->rcItem.left, lpDis->rcItem.top, width, height);
        }
        // If there are no list box items, skip
        break;
    case ODA_FOCUS:
        DrawFocusRect(lpDis->hDC, &lpDis->rcItem);
        break;
    }
}
【Character类】
#include "stdafx.h"
#include "Character.h"

Character::Character(void)
{
    width = height = 32;
}


Character::~Character(void)
{
}

void Character::Close(void)
{
    width = height = 32;
}

void Character::Display(Graphics *graphics, int row, int column, int x, int y)
{
    graphics->DrawImage(image, x, y, column * width, row * height, width, height, UnitPixel);
}

void Character::Display(Graphics *graphics, int row, int column, int x, int y, COLORREF color, int horizontalPadding, int verticalPadding)
{
    Color colorObj;
    colorObj.SetFromCOLORREF(color);
    SolidBrush brush(colorObj);
    graphics->FillRectangle(&brush, x, y, width + 2 * horizontalPadding, height + 2 * verticalPadding);
    Display(graphics, row, column, x + horizontalPadding, y + verticalPadding);
}

void Character::Display(Graphics *graphics, int row, int column, int x, int y, int sysColor, int horizontalPadding, int verticalPadding)
{
    COLORREF color = GetSysColor(sysColor);
    Display(graphics, row, column, x, y, color, horizontalPadding, verticalPadding);
}

UINT Character::GetHeight(void)
{
    return height;
}

UINT Character::GetWidth(void)
{
    return width;
}

void Character::Open(LPTSTR filename)
{
    Open(wstring(filename));
}

void Character::Open(wstring filename)
{
    fileName = filename;
    image = Image::FromFile(filename.c_str());
    fileWidth = image->GetWidth();
    fileHeight = image->GetHeight();
    width = fileWidth / IMG_COUNT_H;
    height = fileHeight / IMG_COUNT_V;
}
一派护法 十九级
4楼 发表于:2016-1-4 13:11
顺便提一下,在Windows的更改图标的对话框中,就有未消除灰色选择框的bug:
一派护法 十九级
5楼 发表于:2016-1-4 14:17
在Win7的shell32.dll中我没找到更改图标的对话框。但在Windows XP的shell32.dll中就有这个对话框,它也是用ListBox控件+自绘来实现的。
如果电脑上只有Win7系统又没有XP的shell32.dll文件,可以去网上下载。
一派护法 十九级
6楼 发表于:2016-1-9 13:13
我在响应WM_DRAWITEM消息的时候,返回的值是FALSE,所以才会出现灰色的矩形框。
如果返回TRUE就没有灰色矩形框了。
一派护法 十九级
7楼 发表于:2016-1-17 11:52
【更简单的方法】
直接在WM_DRAWITEM消息处理中return TRUE
case WM_DRAWITEM:
        pDlgCls->DrawItem(lParam);
        return TRUE; // Important! Return true to remove the default focus rect
一派护法 十九级
8楼 发表于:2016-2-14 22:42
异或运算有一个非常重要的运算定律:对于任意的两个整数a和b,始终满足a ^ b ^ b = a。
因此,当屏幕上任意一种颜色a与虚线框颜色b进行两次异或运算后,都能还原为最初的颜色a。

回复帖子

内容:
用户名: 您目前是匿名发表
验证码:
(快捷键:Ctrl+Enter)
 

本帖信息

点击数:386 回复数:7
评论数: ?
作者:巨大八爪鱼
最后回复:巨大八爪鱼
最后回复时间:2016-2-14 22:42
 
©2010-2024 Arslanbar Ver2.0
除非另有声明,本站采用知识共享署名-相同方式共享 3.0 Unported许可协议进行许可。