Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Edit Control цвет рамки


Автор: ZC1989 30.4.2010, 21:01
поискал по форуму и интернету но не нашёл нигде упоминания о том как можно поменять цвет рамки этого контрола со стилями Static Edge = true и Border = false

да вообще нигде не нашёл про то как менять цвет рамок, только текста и фона...

это вообще возможно? по мсдн лажу но ничего найти не могу...может не так ищу...

Автор: ИванМ 1.5.2010, 00:03
ZC1989, вроде нельзя. Если только свой контрол писать.

Автор: Emura 1.5.2010, 00:30
Цитата

Static Edge = true и Border = false

это визуал студия?
рамку вроде как рисует тема. 
можно например рисовать свою поверх, просабклассив эдит.


а можно реализовать эдит самостоятельно. 
но эта задача не на один день и даже не на одну неделю, тем более если эдит мультилайн. 
к тому же надо знать винапи на зубок. сложно для новичка.


Автор: ZC1989 1.5.2010, 09:59
Emura, у меня были мысли переписать контрол,я так и понял что пока не асилю.
а можно же убрать тогда в студии у этого контрола рамку вовсе,а как тогда нарисовать на нём её? сразу после отрисовки его же?
и ещё,пробовал отлавливать сообщения для перерисовки, WM_COLOREDIT,в нём менял цвет текста SetTextColor, SetBkColor. и почему то фон менялся не под всем контролом, а только под набранным текстом 0.о

п.с.: с кодом попробовать сейчас никак,с телефона сижу

Автор: Emura 1.5.2010, 13:04
возможно есть какое-нибудь сообщение отвечающее за отрисовку рамки, но не припомню. если самому рисовать, то можно попробовать такой вариант.

сабклассим контрол  
отлавливаем WM_PAINT, в нем передаем WM_PAINT в процедуру по умолчанию и после что-то вроде:
Код

GetDC()
Rect()
ReleaseDC()

возвращаем из процедуры 0


Код

case WM_PAINT:
{
истинная процедура(WM_PAINT, ...);
GetDC(...);
Rect(...);
ReleaseDC(...);
return 0;
}



ИМХО 
не стоит заморачиваться с нестандартными контролами, окнами. 
99% пользователей не оценит того огромного времени, которое потратиться на все эти дела!
а если делать, то делать свои контролы полностью, и нужны будут обертки для всех стандартых операций, во внешнем виде которых не будет и намека на винапи. это сильно упростит разработку! ООП - обязательно


Автор: ZC1989 1.5.2010, 13:54
Emura, вот я сейчас попробовал сделать такую штуку, но не сабклассил едит


вот эта функция у меня напрямую вызывается в функции окна
Код

case WM_CTLCOLOREDIT:
    return draw_edits(hwnd, Global_hInst, (HWND)lParam, (HDC)wParam);
    break;
...
...
...
LRESULT draw_edits(HWND hwnd, HINSTANCE hInst, HWND hwndForm, HDC hDC){
        bool Ret = false;
        if(hwndForm == edit_Login.hwnd){
            StaticHDC = hDC;
            MemoryHDC = CreateCompatibleDC(StaticHDC);

            HPEN hPen;
            HGDIOBJ hPenOld;
            LOGBRUSH lb;
            lb.lbStyle = BS_SOLID;
            lb.lbColor = RGB(255,0,0);
            lb.lbHatch = 0;

            hPen = ExtCreatePen(PS_COSMETIC | PS_SOLID, 1, &lb, 0, NULL); 
            hPenOld = SelectObject(StaticHDC, hPen);


// рисую 4 линии рамки
            MoveToEx(StaticHDC, 0, 0, NULL);
            LineTo(StaticHDC, edit_Login.width, 0); 

            MoveToEx(StaticHDC, edit_Login.width, 0, NULL);
            LineTo(StaticHDC, edit_Login.width, edit_Login.height);

            MoveToEx(StaticHDC, 0, 0, NULL);
            LineTo(StaticHDC, 0, edit_Login.height);

            MoveToEx(StaticHDC, 0, edit_Login.height, NULL);
            LineTo(StaticHDC, edit_Login.width, edit_Login.height);

            SelectObject(StaticHDC, hPenOld); 
            DeleteObject(hPen); 

            DeleteDC(MemoryHDC);
            

            //SetTextColor(hDC, edit_Login.color_text);
            //SetBkColor(hDC, edit_Login.color_bg);
            SetBkMode(hDC, TRANSPARENT);


// так как фон прозрачный, я делаю перерисовку фона под едитом
            RECT rect_hwnd;

            rect_hwnd.left = edit_Login.pos_x;
            rect_hwnd.right = edit_Login.pos_x + edit_Login.width;
            rect_hwnd.top = edit_Login.pos_y;
            rect_hwnd.bottom = edit_Login.pos_y + edit_Login.height;
            InvalidateRect(hwnd, &rect_hwnd, FALSE);



            Ret = true;
        }

        if(Ret) return (LRESULT)GetStockObject(NULL_BRUSH);
        return NULL; 
    }


и получает касяк, изза перерисовки фона мерцает слишком сильно весь контрол... а без перерисовки не получается очищать фон...в чём ошибка???

Добавлено через 1 минуту и 21 секунду
на счёт того что бы сабклассить, я это не делал никогда...смутно понимаю что к чему...есть вариант без эксперементов сейчас сделать мне?

Добавлено через 4 минуты и 21 секунду
Цитата

не стоит заморачиваться с нестандартными контролами, окнами. 


я тут стремлюсь больше не для масс, программа узко специализирована...(для управления движком для сайта) поэтому видеть её будут люди связанные с этим...а они оценят я думаю)

Автор: Emura 1.5.2010, 14:55
ZC1989,
WM_CTLCOLOREDIT - никогда не использовал подобных сообщений, поэтому не могу сказать что к чему.  
если мне нужен какой-то контрол, то он делается "с чистого листа".


Цитата

на счёт того что бы сабклассить, я это не делал никогда...смутно понимаю что к чему...есть вариант без эксперементов сейчас сделать мне?

это эксперимент не сложный. наверное знаешь что любое окно использует свою оконную процедуру. сабклассинг ни что иное как замена этой процедуры на другую.

Код

// назначаем свою процедуру, 
// фун-ция возвращает текущую процедуру
WNDPROC oldWinProc =(WNDPROC)::SetWindowLongPtrW( hWndEdit, GWL_WNDPROC, (long)newWindowProcedure );



Цитата

я тут стремлюсь больше не для масс, программа узко специализирована...(для управления движком для сайта) поэтому видеть её будут люди связанные с этим...а они оценят я думаю)

ок, хозяин-барин

Автор: ZC1989 1.5.2010, 15:25
Emura, WM_CTLCOLOREDIT посылается когда оконная процедура перерисовывает один из edit text, я из под такого сообщения для Static (WM_CTLCOLORSTATIC) меняю цвет и прозрачность фона, с ним приходят HWND и HDC контрола который нужно отрисовать, посути. этот же WM_PAINT как был бы если бы я сделал сабклассинг, насколько я понимаю...  smile 

я точно так же из него же сделал отрисовку рамок...

хатя может серьёзно есть большая разница..

вопрос ещё такой (чтоб уж не перерывать щас кучу мануалок) если я сделаю для контрола свою оконную процедуру, то мне полностью придётся обрабатывать всё да? тоесть от цвета вывода до самого написания текста на экране?

Автор: Earnest 4.5.2010, 07:05
ZC1989, рамка рисуется на WM_NCPAINT - если рамка в принципе есть. Достаточно перехватить это сообщение.
Но есть некоторая опасность, что в некоторых ситуациях будет проскакивать стандартная рамка (старые контролы Виндоус не всегда соблюдают собственные соглашения). Насчет эдита не знаю, нужно проверять.
Еще вариант - сдалать контрол без рамки (без стилей WS_BORDER и прочая), но обработать WM_NCCALSIZE, чтобы таки сдвинуть клиентскую область вглубь контрола (на 1-2 пиксела, чтобы было где рамку рисовать). Рисовать, опять же, на WM_NCPAINT.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)