www.gusucode.com > 微软FreeCL开源免费的C++编译器源码源码程序 > 微软FreeCL开源免费的C++编译器源码/FreeCL_Skin.v2.03.Full.Source.ccrun.718306/FreeCL_Skin.v2.03.Full.Source.ccrun.718306/EngineSource/FreeCL/WinEdit.cpp
#include "WinEdit.h" namespace FreeCL { EditDesc::EditDesc(void) { mEdgeStyle = EdgeStyle_Default; mBorderColor = ::GetSysColor(COLOR_3DSHADOW); mMultiLine = false; mAutoHorzScroll = true; mAutoVertScroll = true; mShowHorzScroll = true; mShowVertScroll = true; mLeftScrollBar = false; mSkinScrollBar = false; InitBool(mTextLeft, mTextRight, mTextCenter); mTextLeft = true; InitBool(mConvertLowercase, mConvertUppercase); mOemConvert = false; mHideSelect = true; mNumber = false; mPassword = false; mReadOnly = false; mWantReturn = false; } void EditDesc::InitEditDesc(long wType, long exStyle) { if((exStyle & WS_EX_CLIENTEDGE) == WS_EX_CLIENTEDGE) mEdgeStyle = EdgeStyle_Client; else if((exStyle & WS_EX_STATICEDGE) == WS_EX_STATICEDGE) mEdgeStyle = EdgeStyle_Frame; else mEdgeStyle = EdgeStyle_None; mAutoHorzScroll = bool((wType & ES_AUTOHSCROLL) == ES_AUTOHSCROLL); mMultiLine = bool((wType & ES_MULTILINE) == ES_MULTILINE); if(mMultiLine) { mAutoVertScroll = bool((wType & ES_AUTOVSCROLL) == ES_AUTOVSCROLL); mShowHorzScroll = bool((wType & WS_HSCROLL) == WS_HSCROLL); mShowVertScroll = bool((wType & WS_VSCROLL) == WS_VSCROLL); } else { mAutoVertScroll = false; mShowHorzScroll = false; mShowVertScroll = false; } mLeftScrollBar = bool((exStyle & WS_EX_LEFTSCROLLBAR) == WS_EX_LEFTSCROLLBAR); mSkinScrollBar = false; mTextLeft = bool((wType & ES_LEFT) == ES_LEFT); mTextCenter = bool((wType & ES_CENTER) == ES_CENTER); mTextRight = bool((wType & ES_RIGHT) == ES_RIGHT); mConvertLowercase = bool((wType & ES_LOWERCASE) == ES_LOWERCASE); mConvertUppercase = bool((wType & ES_UPPERCASE) == ES_UPPERCASE); mOemConvert = bool((wType & ES_OEMCONVERT) == ES_OEMCONVERT); mHideSelect = bool((wType & ES_NOHIDESEL) == 0); mNumber = bool((wType & ES_NUMBER) == ES_NUMBER); if(!mMultiLine) mPassword = bool((wType & ES_PASSWORD) == ES_PASSWORD); else mPassword = false; mReadOnly = bool((wType & ES_READONLY) == ES_READONLY); mWantReturn = bool((wType & ES_WANTRETURN) == ES_WANTRETURN); } //----------------------------------------------------------------------------------------------------------------------- WinEdit::WinEdit(void) : mEventBegin(this), mPropertyBegin(this) { m_SkinColor = ::GetSysColor(COLOR_WINDOW); m_TextColor = ::GetSysColor(COLOR_WINDOWTEXT); m_Attach = FALSE; m_NcPaint = TRUE; m_HScroll = FALSE; m_VScroll = FALSE; m_DrawBrush = NULL; m_DrawBitmap = NULL; } WinEdit::~WinEdit(void) { } FreeCL_Optimize bool WinEdit::CreateEdit(WinContainer* parent,int left,int top,int width,int height,EditDesc& desc) { if(parent) { if(desc.mEdgeStyle != EdgeStyle_Default && desc.mEdgeStyle != EdgeStyle_Client && desc.mEdgeStyle != EdgeStyle_Frame && desc.mEdgeStyle != EdgeStyle_None && desc.mEdgeStyle != EdgeStyle_Color) { #ifdef _DEBUG ::DebugBreak(); //非法的边缘风格 #endif return false; } if(byte(desc.mTextLeft)+byte(desc.mTextRight)+byte(desc.mTextCenter) == 0) { #ifdef _DEBUG ::DebugBreak();//3个值必须有一个为true!!! #endif return false; } DWORD exStyle = 0; DWORD wType = WS_TABSTOP | WS_CHILD | WS_CLIPSIBLINGS; if(desc.mLeftScrollBar) exStyle |= WS_EX_LEFTSCROLLBAR; if(desc.mEdgeStyle == EdgeStyle_Client || desc.mEdgeStyle == EdgeStyle_Default) exStyle |= WS_EX_CLIENTEDGE; else if(desc.mEdgeStyle == EdgeStyle_Frame) exStyle |= WS_EX_STATICEDGE; else if(desc.mEdgeStyle == EdgeStyle_Color) exStyle |= WS_EX_STATICEDGE; if(desc.mAutoHorzScroll) wType |= ES_AUTOHSCROLL; if(desc.mMultiLine) wType |= ES_MULTILINE; if(desc.mMultiLine) { if(desc.mAutoVertScroll) wType |= ES_AUTOVSCROLL; if(desc.mShowHorzScroll) wType |= WS_HSCROLL; if(desc.mShowVertScroll) wType |= WS_VSCROLL; } if(desc.mTextLeft) wType |= ES_LEFT; if(desc.mTextRight) wType |= ES_RIGHT; if(desc.mTextCenter) wType |= ES_CENTER; if(desc.mConvertLowercase) wType |= ES_LOWERCASE; if(desc.mConvertUppercase) wType |= ES_UPPERCASE; if(desc.mOemConvert) wType |= ES_OEMCONVERT; if(!desc.mHideSelect) wType |= ES_NOHIDESEL; if(desc.mNumber) wType |= ES_NUMBER; if(!desc.mMultiLine) { if(desc.mPassword) wType |= ES_PASSWORD; } if(desc.mReadOnly) wType |= ES_READONLY; if(desc.mWantReturn) wType |= ES_WANTRETURN; m_Handle = ::CreateWindowEx(exStyle, "Edit", "", wType, left, top, width, height, parent->GetHandle(), NULL, gModule, 0); if(m_Handle) { m_Desc = desc; m_Parent = parent; if(m_Desc.mEdgeStyle != EdgeStyle_Default) { //关闭桌面主题 if(FreeCL::GetBaseThemeEnabled()) FreeCL::SetWindowTheme(m_Handle, L"", L""); } else if(!FreeCL::GetBaseThemeEnabled()) m_Desc.mEdgeStyle = EdgeStyle_Client; m_Left = left; m_Top = top; m_Width = width; m_Height = height; ::SendMessage(m_Handle, WM_SETFONT, (WPARAM)parent->GetFont(), FALSE); ::SetWindowLong(m_Handle, GWL_ID, (LONG)m_Id); SetSkin(false, SkinMode_Color, m_SkinColor, ""); parent->AddWinControl(this); InitScrollControl(m_Handle, m_Desc.mSkinScrollBar); OnControlCreate(); ::ShowWindow(m_Handle,SW_SHOW); return true; } #ifdef _DEBUG else//窗口创建失败(可能传入了非法的参数) ::DebugBreak(); #endif } return false; } bool WinEdit::Attach(HWND edit) { if(edit) { m_Handle = edit; LONG wType = ::GetWindowLong(m_Handle, GWL_STYLE); LONG exStyle = ::GetWindowLong(m_Handle, GWL_EXSTYLE); m_Desc.InitEditDesc(wType, exStyle); if(m_Desc.mEdgeStyle == EdgeStyle_Client) { if(FreeCL::GetBaseThemeEnabled()) { HTHEME theme = FreeCL::OpenThemeData(m_Handle, L"Edit"); if(theme) { m_Desc.mEdgeStyle = EdgeStyle_Default; FreeCL::CloseThemeData(theme); } } } RECT wRect; ::GetWindowRect(m_Handle, &wRect); m_Width = wRect.right - wRect.left; m_Height = wRect.bottom - wRect.top; HWND pWnd = ::GetParent(m_Handle); ::ScreenToClient(pWnd, (POINT*)&wRect); m_Left = wRect.left; m_Top = wRect.top; ::SetWindowLong(m_Handle, GWL_ID, (LONG)m_Id); //Use edit's old font SetSkin(false, SkinMode_Color, m_SkinColor, ""); WinContainer* parent = (WinContainer*)(WinControl::GetControlPointer(pWnd)); DebugAssert(parent->IsContainer()); m_Parent = parent; parent->AddWinControl(this); InitScrollControl(m_Handle, BOOL(m_Desc.mSkinScrollBar)); OnControlCreate(); m_Attach = TRUE; return true; } return false; } bool WinEdit::CreateControl(WinContainer* parent,int left,int top,int width,int height) { EditDesc desc; return CreateEdit(parent,left,top,width,height,desc); } void WinEdit::DestroyControl() { Parent::DestroyControl(); m_Desc = EditDesc(); m_SkinColor = ::GetSysColor(COLOR_WINDOW); m_TextColor = ::GetSysColor(COLOR_WINDOWTEXT); m_NcPaint = TRUE; m_HScroll = FALSE; m_VScroll = FALSE; DestroyDrawData(); } cstr WinEdit::GetClass() { return "WinEdit"; } bool WinEdit::IsEdit() { return true; } sint WinEdit::GetLineFromChar(sint index) { if(m_Handle && 0 <= index && index < GetCharCount()) return ::SendMessage(m_Handle, EM_LINEFROMCHAR, (WPARAM)index, 0); return -1; } sint WinEdit::GetCurrentLine() { if(m_Handle) return ::SendMessage(m_Handle, EM_LINEFROMCHAR, (WPARAM)(-1), 0); return -1; } sint WinEdit::GetFirstCharFromLine(sint index) { if(m_Handle && 0 <= index) return ::SendMessage(m_Handle, EM_LINEINDEX, (WPARAM)index, 0); return -1; } sint WinEdit::GetLineLengthFromChar(sint index) { if(m_Handle) { if(0 <= index) return ::SendMessage(m_Handle, EM_LINELENGTH, index, 0); else return 0; } return -1; } sint WinEdit::CopyLine(sint line, char* buffer, ushort bufferSize) { if(m_Handle && 0 <= line && buffer) { if(m_Desc.mMultiLine) { if(line < GetLineCount()) { *(ushort*)buffer = bufferSize; return ::SendMessage(m_Handle, EM_GETLINE, (WPARAM)line, (LPARAM)buffer); } } else if(line == 0) { *(ushort*)buffer = bufferSize; return ::SendMessage(m_Handle, EM_GETLINE, 0, (LPARAM)buffer); } } return 0; } void WinEdit::SelectText(sint start,sint end) { if(m_Handle) { ::SendMessage(m_Handle, EM_SETSEL, start, end); UpdateScrollBar(); } } void WinEdit::GetSelectRange(sint* start, sint* end) { if(m_Handle && (start || end)) ::SendMessage(m_Handle, EM_GETSEL, WPARAM(start), LPARAM(end)); } void WinEdit::SelectAllText() { SelectText(0,-1); } void WinEdit::CancelSelect() { SelectText(-1,0); } sint WinEdit::GetVertThumb() { if(m_Handle && m_Desc.mMultiLine && m_Desc.mShowVertScroll) return ::SendMessage(m_Handle, EM_GETTHUMB, 0, 0); return -1; } void WinEdit::ScrollCaret() { if(m_Handle) { ::SendMessage(m_Handle, EM_SCROLLCARET, 0, 0); UpdateScrollBar(); } } void WinEdit::ScrollText(sint horz,sint vert) { if(m_Handle && m_Desc.mMultiLine) { ::SendMessage(m_Handle, EM_LINESCROLL, (WPARAM)horz, (LPARAM)vert); UpdateScrollBar(); } } void WinEdit::VertScroll(EditScrollType param) { if(m_Handle && m_Desc.mMultiLine) { ::SendMessage(m_Handle, EM_SCROLL, (WPARAM)param, 0); //UpdateScrollBar(); //It is same with WM_VSCROLL } } bool WinEdit::ReplaceText(cstr string,bool undo) { if(m_Handle) { DWORD start = 0, end = 0; ::SendMessage(m_Handle, EM_GETSEL, (WPARAM)&start, (LPARAM)&end); if(start < end)//当前必须存在选择的文本才能执行替换操作 { ::SendMessage(m_Handle, EM_REPLACESEL, BOOL(undo), (LPARAM)string); UpdateScrollBar(); return true; } } return false; } bool WinEdit::DeleteSelect(bool undo) { return ReplaceText("", undo); } bool WinEdit::InsertText(cstr string, bool undo) { if(m_Handle) { DWORD start = 0, end = 0; ::SendMessage(m_Handle, EM_GETSEL, (WPARAM)&start, (LPARAM)&end); if(start == end)//必须不存在选择文本方能执行文本插入操作 { ::SendMessage(m_Handle, EM_REPLACESEL, BOOL(undo), (LPARAM)string); UpdateScrollBar(); return true; } } return false; } void WinEdit::SetTabSpace(uint space, bool redraw) { if(m_Handle && m_Desc.mMultiLine) { BOOL error = ::SendMessage(m_Handle, EM_SETTABSTOPS, 1, (LPARAM)&space); if(error && redraw && IsVisible()) RedrawControl(false); } } void WinEdit::SetLimitText(sint limit) { if(m_Handle) ::SendMessage(m_Handle, EM_LIMITTEXT, limit, 0); } sint WinEdit::GetLimitText() { if(m_Handle) return ::SendMessage(m_Handle, EM_GETLIMITTEXT, 0, 0); return -1; } void WinEdit::SetLeftMargin(sint margin) { if(m_Handle) { ::SendMessage(m_Handle, EM_SETMARGINS, EC_LEFTMARGIN, (LPARAM)(ushort)(short)margin); UpdateScrollBar(); } } sint WinEdit::GetLeftMargin() { if(m_Handle) return (int)(short)(ushort)(0x0000FFFF & (DWORD)::SendMessage(m_Handle, EM_GETMARGINS, 0, 0)); return -1; } void WinEdit::SetRightMargin(sint m) { if(m_Handle) { ::SendMessage(m_Handle, EM_SETMARGINS, EC_RIGHTMARGIN, LPARAM(DWORD(ushort(short(m)))<<16)); UpdateScrollBar(); } } sint WinEdit::GetRightMargin() { if(m_Handle) return (int)(short)(ushort)(DWORD(::SendMessage(m_Handle, EM_GETMARGINS, 0, 0)) >> 16); return -1; } void WinEdit::SetCaption(cstr text) { if(m_Handle) { ::SetWindowText(m_Handle, text); //把光标位置移动到末尾 int count = GetCharCount(); SelectText(count, count); UpdateScrollBar(); } } cstr WinEdit::GetCaption() { if(m_Handle) { int len = ::GetWindowTextLength(m_Handle); if(len > 0) { if(int(m_Caption.size()) < len+1) m_Caption.resize(len+1); ::GetWindowText(m_Handle, &m_Caption[0], int(m_Caption.size())); return m_Caption.c_str(); } return ""; } return NULL; } bool WinEdit::CanUndo() { if(m_Handle) return bool(::SendMessage(m_Handle, EM_CANUNDO, 0, 0) != 0); return false; } bool WinEdit::Undo() { if(m_Handle) { bool bCode = bool(::SendMessage(m_Handle, EM_UNDO, 0, 0) != 0); if(bCode) UpdateScrollBar(); return bCode; } return false; } void WinEdit::ResetUndoBuffer() { if(m_Handle) ::SendMessage(m_Handle, EM_EMPTYUNDOBUFFER, 0, 0); } void WinEdit::Copy() { if(m_Handle) ::SendMessage(m_Handle, WM_COPY, 0, 0); } void WinEdit::Cut() { if(m_Handle) { ::SendMessage(m_Handle, WM_CUT, 0, 0); UpdateScrollBar(); } } void WinEdit::Clear() { if(m_Handle) { ::SendMessage(m_Handle, WM_CLEAR, 0, 0); UpdateScrollBar(); } } void WinEdit::Paste() { if(m_Handle) { ::SendMessage(m_Handle, WM_PASTE, 0, 0); UpdateScrollBar(); } } sint WinEdit::GetCharFromPoint(const Point& p, sint* line) { if(m_Handle) { DWORD coord = ((DWORD)(ushort)(short)p.x) | (((DWORD)(ushort)(short)p.y) << 16); DWORD cl = ::SendMessage(m_Handle, EM_CHARFROMPOS, 0, (LPARAM)coord); if(line) *line = int(short(HIWORD(cl))); return int(short(LOWORD(cl))); } return -1; } Point WinEdit::GetPointFromChar(sint index) { Point p(LONG_MIN, LONG_MIN); if(m_Handle && index >= 0) { LRESULT error = ::SendMessage(m_Handle, EM_POSFROMCHAR, (WPARAM)index, 0); if(error != -1) { DWORD coord = (DWORD)error; p.x = (long)(short)(ushort)LOWORD(coord); p.y = (long)(short)(ushort)HIWORD(coord); } } return p; } void WinEdit::SetText(cstr text) { SetCaption(text); } cstr WinEdit::GetText() { return GetCaption(); } void WinEdit::SetTextColor(uint color) { if(m_Handle && color != m_TextColor) { m_TextColor = color; if(IsVisible()) RedrawControl(false); } } uint WinEdit::GetTextColor() { return m_TextColor; } sint WinEdit::GetCharCount() { if(m_Handle) return ::SendMessage(m_Handle, WM_GETTEXTLENGTH, 0, 0); return -1; } sint WinEdit::GetLineCount() { if(m_Handle) { if(m_Desc.mMultiLine) return ::SendMessage(m_Handle, EM_GETLINECOUNT, 0, 0); else return 1; } return -1; } sint WinEdit::GetTopLine() { if(m_Handle) { if(m_Desc.mMultiLine) return ::SendMessage(m_Handle, EM_GETFIRSTVISIBLELINE, 0, 0); else return 0; } return -1; } void WinEdit::SetModifyFlag(bool f) { if(m_Handle) ::SendMessage(m_Handle, EM_SETMODIFY, BOOL(f), 0); } bool WinEdit::GetModifyFlag() { if(m_Handle) return bool(::SendMessage(m_Handle, EM_GETMODIFY, 0, 0) != 0); return false; } void WinEdit::SetPassword(char c) { if(m_Handle && !m_Desc.mMultiLine && m_Desc.mPassword) ::SendMessage(m_Handle, EM_SETPASSWORDCHAR, WPARAM(c), 0); } char WinEdit::GetPassword() { if(m_Handle && !m_Desc.mMultiLine && m_Desc.mPassword) return(char)::SendMessage(m_Handle, EM_GETPASSWORDCHAR, 0, 0); return 0; } void WinEdit::SetSelectStart(sint start) { SelectText(start, start); } sint WinEdit::GetSelectStart() { int start = -1; GetSelectRange(&start, NULL); return start; } void WinEdit::SetSelectEnd(sint end) { if(m_Handle) SelectText(GetSelectStart(), end); } sint WinEdit::GetSelectEnd() { int end = -1; GetSelectRange(NULL, &end); return end; } void WinEdit::SetFormatRect(Rect rect) { if(m_Handle && m_Desc.mMultiLine) { if(rect != Rect()) ::SendMessage(m_Handle, EM_SETRECT, 0, (LPARAM)&rect); else ::SendMessage(m_Handle, EM_SETRECT, 0, 0); UpdateScrollBar(); } } Rect WinEdit::GetFormatRect() { Rect rect; if(m_Handle && m_Desc.mMultiLine) ::SendMessage(m_Handle, EM_GETRECT, 0, (LPARAM)&rect); return rect; } void WinEdit::SetReadOnly(bool ro) { if(m_Handle) ::SendMessage(m_Handle, EM_SETREADONLY, BOOL(ro), 0); } bool WinEdit::GetReadOnly() { if(m_Handle) { if((::GetWindowLong(m_Handle, GWL_STYLE) & EM_SETREADONLY) == EM_SETREADONLY) return true; } return false; } void WinEdit::SetMemHandle(HLOCAL h) { if(m_Handle && m_Desc.mMultiLine) ::SendMessage(m_Handle, EM_SETHANDLE, WPARAM(h), 0); } HLOCAL WinEdit::GetMemHandle() { if(m_Handle && m_Desc.mMultiLine) return (HLOCAL)::SendMessage(m_Handle, EM_GETHANDLE, 0, 0); return NULL; } LRESULT WinEdit::WmMove(WPARAM wParam, LPARAM lParam) { if(!m_MoveSize) { //系统可能会自动调整控件位置(如Rebar控件可能更改其所捆绑的控件位置) RECT wRect; ::GetWindowRect(m_Handle, &wRect); ::ScreenToClient(GetParent()->GetHandle(), (POINT*)&wRect); m_Left = wRect.left; m_Top = wRect.top; } if(UseDrawData()) { DestroyDrawData(); RedrawControl(true); } else if(m_ParentSkin) { SkinMode pMode = GetSkinMode(); if(pMode == SkinMode_BitmapResource || pMode == SkinMode_BitmapFile) RedrawControl(true); } return TRUE; } LRESULT WinEdit::WmSize(WPARAM wParam, LPARAM lParam) { if(!m_MoveSize) { //系统可能会自动调整控件尺寸 RECT wRect; ::GetWindowRect(m_Handle, &wRect); m_Width = wRect.right - wRect.left; m_Height = wRect.bottom - wRect.top; } if(UseDrawData()) { DestroyDrawData(); RedrawControl(true); } return TRUE; } LRESULT WinEdit::WmChar(WPARAM wParam, LPARAM lParam) { if(mOnChar != NULL) { CallDefaultProc(WM_CHAR, wParam, lParam); if(!mOnChar.mThis) (GetParent()->*mOnChar)(this, char(wParam)); else mOnChar(this, char(wParam)); return 0; } return TRUE; } LRESULT WinEdit::WmLButtonUp(WPARAM wParam, LPARAM lParam) { if(!IsMinXP())//这几行代码对XP或更新的系统似乎多余,老系统可能需要。若有问题,用户可注释if语句 { if(UseBitmapSkin()) RedrawControl(false); } return TRUE; } LRESULT WinEdit::WmHScroll(WPARAM wParam, LPARAM lParam) { if(UseBitmapSkin() && !m_HScroll && !m_VScroll) { //某些老版本的系统可能会因键盘按下事件而引发滚动条事件 WORD code = LOWORD(wParam); if(code != SB_ENDSCROLL && code != SB_THUMBPOSITION) { if(code == SB_THUMBTRACK) { //拖拽抓取器时,系统并不触发画布滚动事件 if(int(SHORT(HIWORD(wParam))) == GetHorzThumbPosition()) return TRUE; } else { //单击滚动条的箭头按钮或单击其空白区域会有画布的滚动事件 if(code == SB_LINELEFT || code == SB_PAGELEFT || code == SB_LEFT) { if(GetHorzThumbPosition() == GetHorzScrollMin()) return TRUE; } else if(code == SB_LINERIGHT || code == SB_PAGERIGHT || code == SB_RIGHT) { if(GetHorzThumbPosition() == GetHorzScrollMax()) return TRUE; } } //第一步:Edit对滚动消息的处理会滚动客户区,导致皮肤位图也发生平移,因此我们主动这个滚动操作 ::SendMessage(m_Handle, WM_SETREDRAW, FALSE, 0); CallDefaultProc(WM_HSCROLL, wParam, lParam); ::SendMessage(m_Handle, WM_SETREDRAW, TRUE, 0); //第二步:主动刷新背景,但这个操作会导致滚动条刷新异常,因此在滚动条刷新的WM_NCPAINT处理直接绕过去 m_NcPaint = FALSE; ::InvalidateRect(m_Handle, NULL, TRUE); ::UpdateWindow(m_Handle); // This call can triger WM_NCPAINT & WM_PAINT m_NcPaint = TRUE; SetHorzThumbPosition(GetHorzThumbPosition(), true); if(code == SB_THUMBTRACK && mOnHorzScroll != NULL) { if(!mOnHorzScroll.mThis) (GetParent()->*mOnHorzScroll)(this); else mOnHorzScroll(this); } return 0; } } return TRUE; } LRESULT WinEdit::WmVScroll(WPARAM wParam, LPARAM lParam) { //Only multi-line edit if(UseBitmapSkin() && !m_HScroll && !m_VScroll) { WORD code = LOWORD(wParam); if(code != SB_ENDSCROLL && code != SB_THUMBPOSITION) { if(code == SB_THUMBTRACK) { if(int(SHORT(HIWORD(wParam))) == GetVertThumbPosition()) return TRUE; } else { if(code == SB_LINEUP || code == SB_PAGEUP || code == SB_TOP) { if(GetVertThumbPosition() == GetVertScrollMin()) return TRUE; } else if(code == SB_LINEDOWN || code == SB_PAGEDOWN || code == SB_BOTTOM) { if(GetVertThumbPosition() == GetVertScrollMax()) return TRUE; } } ::SendMessage(m_Handle, WM_SETREDRAW, FALSE, 0); CallDefaultProc(WM_VSCROLL, wParam, lParam); ::SendMessage(m_Handle, WM_SETREDRAW, TRUE, 0); m_NcPaint = FALSE; ::InvalidateRect(m_Handle, NULL, TRUE); ::UpdateWindow(m_Handle); m_NcPaint = TRUE; SetVertThumbPosition(GetVertThumbPosition(), true); if(code == SB_THUMBTRACK && mOnVertScroll != NULL) { if(!mOnVertScroll.mThis) (GetParent()->*mOnVertScroll)(this); else mOnVertScroll(this); } return 0; } } return TRUE; } LRESULT WinEdit::WmKeyDown(WPARAM wParam, LPARAM lParam) { if(UseBitmapSkin()) { if((wParam == VK_LEFT || wParam == VK_RIGHT || wParam == VK_HOME || wParam == VK_END) || (m_Desc.mMultiLine && (wParam == VK_UP || wParam == VK_DOWN || wParam == VK_NEXT || wParam == VK_PRIOR))) { m_HScroll = TRUE; // m_VScroll = TRUE; //这两个标志监视画布的滚动 CallDefaultProc(WM_KEYDOWN, wParam, lParam); if(!m_HScroll || !m_VScroll) { ::SendMessage(m_Handle, WM_SETREDRAW, TRUE, 0); ::InvalidateRect(m_Handle, NULL, TRUE); ::UpdateWindow(m_Handle); } m_HScroll = FALSE; m_VScroll = FALSE; return 0; } } return TRUE; } LRESULT WinEdit::WmMouseWheel(WPARAM wParam, LPARAM lParam) { //鼠标滚轮事件仅对多行编辑控件有效 if(m_Desc.mMultiLine && UseBitmapSkin()) { m_HScroll = TRUE; // m_VScroll = TRUE; //这两个标志监视画布的滚动 CallDefaultProc(WM_MOUSEWHEEL, wParam, lParam); if(!m_HScroll || !m_VScroll) { ::SendMessage(m_Handle, WM_SETREDRAW, TRUE, 0); ::InvalidateRect(m_Handle, NULL, TRUE); ::UpdateWindow(m_Handle); } m_HScroll = FALSE; m_VScroll = FALSE; return 0; } return TRUE; } LRESULT WinEdit::WmEraseBkGnd(WPARAM wParam, LPARAM lParam) { /*返回TRUE在多行编辑控件产生渲染上的一些问题,此消息似乎不可重载*/ return 0; } LRESULT WinEdit::WmThemeChanged(WPARAM wParam, LPARAM lParam) { static BOOL sReEnter = FALSE; if(sReEnter) return TRUE; DestroyDrawData(); CallDefaultProc(WM_THEMECHANGED, wParam, lParam); FreeCL::InitTheme(); ::SendMessage(m_Handle, WM_SETFONT, WPARAM(m_Parent->GetFont()), (LPARAM)TRUE); if(!FreeCL::GetBaseThemeEnabled()) { if(m_Desc.mEdgeStyle == EdgeStyle_Default) m_Desc.mEdgeStyle = EdgeStyle_Client; } else if(m_Desc.mEdgeStyle != EdgeStyle_Default) { sReEnter = TRUE; FreeCL::SetWindowTheme(m_Handle, L"", L""); sReEnter = FALSE; } return 0; } bool WinEdit::UseDrawData() { if(mOnDrawSkin != NULL || (m_ParentSkin && GetBrush() == NULL)) return true; return false; } bool WinEdit::UseBitmapSkin() { if(UseDrawData()) return true; SkinMode cMode = GetSkinMode(); if(cMode == SkinMode_BitmapResource || cMode == SkinMode_BitmapFile) return true; return false; } void WinEdit::CreateDrawData(HDC dc) { if(!m_DrawBrush) { RECT cRect; ::GetClientRect(m_Handle, &cRect); HDC memDC = ::CreateCompatibleDC(dc); m_DrawBitmap = ::CreateCompatibleBitmap(dc, cRect.right-cRect.left, cRect.bottom-cRect.top); HGDIOBJ iBitmap = ::SelectObject(memDC, m_DrawBitmap); EditSkinData data; data.mDC = memDC; bool bCode = true; if(mOnDrawSkin != NULL) { if(!mOnDrawSkin.mThis) bCode = (GetParent()->*mOnDrawSkin)(this, data); else bCode = mOnDrawSkin(this, data); } if(bCode) DrawSkin(memDC, &cRect); ::SelectObject(memDC, iBitmap); ::DeleteDC(memDC); m_DrawBrush = ::CreatePatternBrush(m_DrawBitmap); } } void WinEdit::DestroyDrawData() { if(m_DrawBrush) { ::DeleteObject(m_DrawBrush); m_DrawBrush = NULL; } if(m_DrawBitmap) { ::DeleteObject(m_DrawBitmap); m_DrawBitmap = NULL; } } LRESULT WinEdit::WmOwnerCtlColor(WPARAM wParam, LPARAM lParam) { HDC dc = (HDC)wParam; ::SetTextColor(dc, this->GetTextColor());//注意:必须返回一个有效的刷子,颜色设置才能生效 ::SetBrushOrgEx(dc, 0, 0, NULL); HBRUSH brush = NULL; if(UseDrawData()) { ::SetBkMode(dc, TRANSPARENT); CreateDrawData(dc); brush = m_DrawBrush; } else { brush = GetBrush(); SkinMode cMode = GetSkinMode(); if(cMode == SkinMode_Color) ::SetBkColor(dc, GetSkinColor()); else if(cMode == SkinMode_BitmapResource || cMode == SkinMode_BitmapFile) { //位图背景 WINDOWINFO wInfo; memset(&wInfo, 0, sizeof(wInfo)); wInfo.cbSize = sizeof(wInfo); ::GetWindowInfo(m_Handle, &wInfo); POINT iPoint; iPoint.x = wInfo.rcClient.left; iPoint.y = wInfo.rcClient.top; ::ScreenToClient(GetSkinControl()->GetHandle(), (POINT*)&iPoint); ::SetBrushOrgEx(dc, -iPoint.x, -iPoint.y, NULL);//刷子对齐 ::SetBkMode(dc, TRANSPARENT); } } return (LRESULT)brush; } BOOL WinEdit::DrawScrollBarSkin(HDC dc, const RECT& cRect, const POINT& rOffset) { if(mOnDrawScrollSkin != NULL) { bool bCode; ScrollBarSkinData data; data.mDC = dc; data.mClipRect = *(Rect*)&cRect; if(!mOnDrawScrollSkin.mThis) bCode = (GetParent()->*mOnDrawScrollSkin)(this, data); else bCode = mOnDrawScrollSkin(this, data); if(!bCode) return FALSE;//返回FALSE阻止默认的灰色背景绘制 } if(GetSkinEnabled()) { DrawSkin(dc, &cRect, rOffset.x, rOffset.y); return FALSE; } return TRUE; } BOOL WinEdit::DrawScrollBarPart(HDC dc, const RECT& iRect, const RECT& cRect,const POINT& rOffset, ScrollPart part, BOOL enabled, BOOL pressed, BOOL hilited) { if(mOnDrawScrollPart != NULL) { ScrollBarDrawData data; data.mDC = dc; data.mRect = *(Rect*)&iRect; data.mClipRect = *(Rect*)&cRect; data.mOffset = *(Point*)&rOffset; data.mElement = part; data.mEnabled = bool(enabled != FALSE); data.mPressed = bool(pressed != FALSE); data.mHilited = bool(hilited != FALSE); bool bCode = true; if(!mOnDrawScrollPart.mThis) bCode = (GetParent()->*mOnDrawScrollPart)(this, data); else bCode = mOnDrawScrollPart(this, data); if(!bCode) return FALSE; } if(GetSkinEnabled()) { BOOL frame = BOOL(m_Desc.mEdgeStyle == EdgeStyle_Frame || m_Desc.mEdgeStyle == EdgeStyle_Color || m_Desc.mEdgeStyle == EdgeStyle_None || m_Desc.mEdgeStyle == EdgeStyle_Default); if(part == ScrollPart_Left) { DrawButtonBox(dc, iRect, frame, pressed, TRUE); DrawArrow(dc, iRect, TRUE, TRUE, enabled, pressed); } else if(part == ScrollPart_Right) { DrawButtonBox(dc, iRect, frame, pressed, TRUE); DrawArrow(dc, iRect, TRUE, FALSE, enabled, pressed); } else if(part == ScrollPart_HorzThumb || part == ScrollPart_VertThumb) DrawButtonBox(dc, iRect, frame, FALSE); else if(part == ScrollPart_Top) { DrawButtonBox(dc, iRect, frame, pressed, TRUE); DrawArrow(dc, iRect, FALSE, TRUE, enabled, pressed); } else if(part == ScrollPart_Bottom) { DrawButtonBox(dc, iRect, frame, pressed, TRUE); DrawArrow(dc, iRect, FALSE, FALSE, enabled, pressed); } return FALSE; } return TRUE; } bool WinEdit::SetSkin(bool parentSkin, SkinMode mode, uint color, cstr name) { if(Parent::SetSkin(parentSkin, mode, color, name)) { DestroyDrawData(); return true; } return false; } LRESULT WinEdit::WmNcPaint(WPARAM wParam, LPARAM lParam) { if(!m_NcPaint) return 0; if(m_Desc.mEdgeStyle == EdgeStyle_Color) { int bWidth = ::GetSystemMetrics(SM_CXBORDER); RECT cRect,wRect; ::GetWindowRect(m_Handle, &wRect); cRect = wRect; ::InflateRect(&cRect, -bWidth, -bWidth); HRGN wRgn = NULL; if(wParam == 1) wRgn = ::CreateRectRgn(wRect.left, wRect.top, wRect.right, wRect.bottom); else wRgn = (HRGN)wParam; HRGN sRgn = ::CreateRectRgn(cRect.left, cRect.top, cRect.right, cRect.bottom); ::CombineRgn(wRgn, wRgn, sRgn, RGN_AND); ::DeleteObject(sRgn); LRESULT lReturn = CallDefaultProc(WM_NCPAINT, WPARAM(wRgn), 0); if(wParam == 1) ::DeleteObject(wRgn); DrawColorBorder(m_Handle, m_Desc.mBorderColor); return lReturn; } return TRUE; } LRESULT WinEdit::WmOwnerCommand(WPARAM wParam, LPARAM lParam) { WORD hw = HIWORD(wParam); if(hw == EN_UPDATE) { if(mOnUpdate != NULL) { if(!mOnUpdate.mThis) (GetParent()->*mOnUpdate)(this); else mOnUpdate(this); return 0; } } else if(hw == EN_CHANGE) { if(!IsMinVista()) { //这3行代码对Vista似乎多余,屏蔽则减轻闪烁,XP是必须的。若有问题,用户可注释if语句 if(UseBitmapSkin()) { ::InvalidateRect(m_Handle, NULL, TRUE); ::UpdateWindow(m_Handle); } } if(mOnChange != NULL) { if(!mOnChange.mThis) (GetParent()->*mOnChange)(this); else mOnChange(this); return 0; } } else if(hw == EN_ERRSPACE) { if(mOnErrorSpace != NULL) { if(!mOnErrorSpace.mThis) (GetParent()->*mOnErrorSpace)(this); else mOnErrorSpace(this); return 0; } } else if(hw == EN_HSCROLL) { //当用户拖拽滚动条时,却不触发滚动消息 if(m_HScroll) { ::SendMessage(m_Handle, WM_SETREDRAW, FALSE, 0); m_HScroll = FALSE; } if(mOnHorzScroll != NULL) { if(!mOnHorzScroll.mThis) (GetParent()->*mOnHorzScroll)(this); else mOnHorzScroll(this); return 0; } } else if(hw == EN_VSCROLL) { if(m_VScroll) { ::SendMessage(m_Handle, WM_SETREDRAW, FALSE, 0); m_VScroll = FALSE; } if(mOnVertScroll != NULL) { if(!mOnVertScroll.mThis) (GetParent()->*mOnVertScroll)(this); else mOnVertScroll(this); return 0; } } else if(hw == EN_KILLFOCUS) { if(mOnKillFocus != NULL) { if(!mOnKillFocus.mThis) (GetParent()->*mOnKillFocus)(this); else mOnKillFocus(this); return 0; } } else if(hw == EN_SETFOCUS) { if(mOnSetFocus != NULL) { if(!mOnSetFocus.mThis) (GetParent()->*mOnSetFocus)(this); else mOnSetFocus(this); return 0; } } else if(hw == EN_MAXTEXT) { if(mOnMaxText != NULL) { if(!mOnMaxText.mThis) (GetParent()->*mOnMaxText)(this); else mOnMaxText(this); return 0; } } return TRUE; } }