?? platwin.cxx
字號:
TEXTMETRIC tm;
::GetTextMetrics(hdc, &tm);
return tm.tmHeight;
}
int SurfaceImpl::AverageCharWidth(Font &font_) {
SetFont(font_);
TEXTMETRIC tm;
::GetTextMetrics(hdc, &tm);
return tm.tmAveCharWidth;
}
int SurfaceImpl::SetPalette(Palette *pal, bool inBackGround) {
if (paletteOld) {
::SelectPalette(hdc, paletteOld, TRUE);
}
paletteOld = 0;
int changes = 0;
if (pal->allowRealization) {
paletteOld = ::SelectPalette(hdc,
reinterpret_cast<HPALETTE>(pal->hpal), inBackGround);
changes = ::RealizePalette(hdc);
}
return changes;
}
void SurfaceImpl::SetClip(PRectangle rc) {
::IntersectClipRect(hdc, rc.left, rc.top, rc.right, rc.bottom);
}
void SurfaceImpl::FlushCachedState() {
pen = 0;
brush = 0;
font = 0;
}
void SurfaceImpl::SetUnicodeMode(bool unicodeMode_) {
unicodeMode=unicodeMode_;
}
void SurfaceImpl::SetDBCSMode(int codePage_) {
// No action on window as automatically handled by system.
codePage = codePage_;
win9xACPSame = !IsNT() && ((unsigned int)codePage == ::GetACP());
}
Surface *Surface::Allocate() {
return new SurfaceImpl;
}
Window::~Window() {
}
void Window::Destroy() {
if (id)
::DestroyWindow(reinterpret_cast<HWND>(id));
id = 0;
}
bool Window::HasFocus() {
return ::GetFocus() == id;
}
PRectangle Window::GetPosition() {
RECT rc;
::GetWindowRect(reinterpret_cast<HWND>(id), &rc);
return PRectangle(rc.left, rc.top, rc.right, rc.bottom);
}
void Window::SetPosition(PRectangle rc) {
::SetWindowPos(reinterpret_cast<HWND>(id),
0, rc.left, rc.top, rc.Width(), rc.Height(), SWP_NOZORDER|SWP_NOACTIVATE);
}
void Window::SetPositionRelative(PRectangle rc, Window w) {
LONG style = ::GetWindowLong(reinterpret_cast<HWND>(id), GWL_STYLE);
if (style & WS_POPUP) {
RECT rcOther;
::GetWindowRect(reinterpret_cast<HWND>(w.GetID()), &rcOther);
rc.Move(rcOther.left, rcOther.top);
// Retrieve desktop bounds and make sure window popup's origin isn't left-top of the screen.
RECT rcDesktop = {0, 0, 0, 0};
#ifdef SM_XVIRTUALSCREEN
rcDesktop.left = ::GetSystemMetrics(SM_XVIRTUALSCREEN);
rcDesktop.top = ::GetSystemMetrics(SM_YVIRTUALSCREEN);
rcDesktop.right = rcDesktop.left + ::GetSystemMetrics(SM_CXVIRTUALSCREEN);
rcDesktop.bottom = rcDesktop.top + ::GetSystemMetrics(SM_CYVIRTUALSCREEN);
#endif
if (rc.left < rcDesktop.left) {
rc.Move(rcDesktop.left - rc.left,0);
}
if (rc.top < rcDesktop.top) {
rc.Move(0,rcDesktop.top - rc.top);
}
}
SetPosition(rc);
}
PRectangle Window::GetClientPosition() {
RECT rc={0,0,0,0};
if (id)
::GetClientRect(reinterpret_cast<HWND>(id), &rc);
return PRectangle(rc.left, rc.top, rc.right, rc.bottom);
}
void Window::Show(bool show) {
if (show)
::ShowWindow(reinterpret_cast<HWND>(id), SW_SHOWNOACTIVATE);
else
::ShowWindow(reinterpret_cast<HWND>(id), SW_HIDE);
}
void Window::InvalidateAll() {
::InvalidateRect(reinterpret_cast<HWND>(id), NULL, FALSE);
}
void Window::InvalidateRectangle(PRectangle rc) {
RECT rcw = RectFromPRectangle(rc);
::InvalidateRect(reinterpret_cast<HWND>(id), &rcw, FALSE);
}
static LRESULT Window_SendMessage(Window *w, UINT msg, WPARAM wParam=0, LPARAM lParam=0) {
return ::SendMessage(reinterpret_cast<HWND>(w->GetID()), msg, wParam, lParam);
}
void Window::SetFont(Font &font) {
Window_SendMessage(this, WM_SETFONT,
reinterpret_cast<WPARAM>(font.GetID()), 0);
}
void Window::SetCursor(Cursor curs) {
switch (curs) {
case cursorText:
::SetCursor(::LoadCursor(NULL,IDC_IBEAM));
break;
case cursorUp:
::SetCursor(::LoadCursor(NULL,IDC_UPARROW));
break;
case cursorWait:
::SetCursor(::LoadCursor(NULL,IDC_WAIT));
break;
case cursorHoriz:
::SetCursor(::LoadCursor(NULL,IDC_SIZEWE));
break;
case cursorVert:
::SetCursor(::LoadCursor(NULL,IDC_SIZENS));
break;
case cursorHand:
::SetCursor(::LoadCursor(NULL,IDC_HAND));
break;
case cursorReverseArrow: {
if (!hinstPlatformRes)
hinstPlatformRes = ::GetModuleHandle(TEXT("Scintilla"));
if (!hinstPlatformRes)
hinstPlatformRes = ::GetModuleHandle(TEXT("SciLexer"));
if (!hinstPlatformRes)
hinstPlatformRes = ::GetModuleHandle(NULL);
HCURSOR hcursor = ::LoadCursor(hinstPlatformRes, MAKEINTRESOURCE(IDC_MARGIN));
if (hcursor)
::SetCursor(hcursor);
else
::SetCursor(::LoadCursor(NULL,IDC_ARROW));
}
break;
case cursorArrow:
case cursorInvalid: // Should not occur, but just in case.
::SetCursor(::LoadCursor(NULL,IDC_ARROW));
break;
}
}
void Window::SetTitle(const char *s) {
::SetWindowText(reinterpret_cast<HWND>(id), s);
}
struct ListItemData {
const char *text;
int pixId;
};
#define _ROUND2(n,pow2) \
( ( (n) + (pow2) - 1) & ~((pow2) - 1) )
class LineToItem {
char *words;
int wordsCount;
int wordsSize;
ListItemData *data;
int len;
int count;
private:
void FreeWords() {
delete []words;
words = NULL;
wordsCount = 0;
wordsSize = 0;
}
char *AllocWord(const char *word);
public:
LineToItem() : words(NULL), wordsCount(0), wordsSize(0), data(NULL), len(0), count(0) {
}
~LineToItem() {
Clear();
}
void Clear() {
FreeWords();
delete []data;
data = NULL;
len = 0;
count = 0;
}
ListItemData *Append(const char *text, int value);
ListItemData Get(int index) const {
if (index >= 0 && index < count) {
return data[index];
} else {
ListItemData missing = {"", -1};
return missing;
}
}
int Count() const {
return count;
}
ListItemData *AllocItem();
void SetWords(char *s) {
words = s; // N.B. will be deleted on destruction
}
};
char *LineToItem::AllocWord(const char *text) {
int chars = strlen(text) + 1;
int newCount = wordsCount + chars;
if (newCount > wordsSize) {
wordsSize = _ROUND2(newCount * 2, 8192);
char *wordsNew = new char[wordsSize];
memcpy(wordsNew, words, wordsCount);
int offset = wordsNew - words;
for (int i=0; i<count; i++)
data[i].text += offset;
delete []words;
words = wordsNew;
}
char *s = &words[wordsCount];
wordsCount = newCount;
strncpy(s, text, chars);
return s;
}
ListItemData *LineToItem::AllocItem() {
if (count >= len) {
int lenNew = _ROUND2((count+1) * 2, 1024);
ListItemData *dataNew = new ListItemData[lenNew];
memcpy(dataNew, data, count * sizeof(ListItemData));
delete []data;
data = dataNew;
len = lenNew;
}
ListItemData *item = &data[count];
count++;
return item;
}
ListItemData *LineToItem::Append(const char *text, int imageIndex) {
ListItemData *item = AllocItem();
item->text = AllocWord(text);
item->pixId = imageIndex;
return item;
}
const TCHAR ListBoxX_ClassName[] = TEXT("ListBoxX");
ListBox::ListBox() {
}
ListBox::~ListBox() {
}
class ListBoxX : public ListBox {
int lineHeight;
FontID fontCopy;
XPMSet xset;
LineToItem lti;
HWND lb;
bool unicodeMode;
int desiredVisibleRows;
unsigned int maxItemCharacters;
unsigned int aveCharWidth;
Window *parent;
int ctrlID;
CallBackAction doubleClickAction;
void *doubleClickActionData;
const char *widestItem;
unsigned int maxCharWidth;
int resizeHit;
PRectangle rcPreSize;
Point dragOffset;
Point location; // Caret location at which the list is opened
HWND GetHWND() const;
void AppendListItem(const char *startword, const char *numword);
void AdjustWindowRect(PRectangle *rc) const;
int ItemHeight() const;
int MinClientWidth() const;
int TextOffset() const;
Point GetClientExtent() const;
Point MinTrackSize() const;
Point MaxTrackSize() const;
void SetRedraw(bool on);
void OnDoubleClick();
void ResizeToCursor();
void StartResize(WPARAM);
int NcHitTest(WPARAM, LPARAM) const;
void CentreItem(int);
void Paint(HDC);
void Erase(HDC);
static LRESULT PASCAL ControlWndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam);
static const Point ItemInset; // Padding around whole item
static const Point TextInset; // Padding around text
static const Point ImageInset; // Padding around image
public:
ListBoxX() : lineHeight(10), fontCopy(0), lb(0), unicodeMode(false),
desiredVisibleRows(5), maxItemCharacters(0), aveCharWidth(8),
parent(NULL), ctrlID(0), doubleClickAction(NULL), doubleClickActionData(NULL),
widestItem(NULL), maxCharWidth(1), resizeHit(0) {
}
virtual ~ListBoxX() {
if (fontCopy) {
::DeleteObject(fontCopy);
fontCopy = 0;
}
}
virtual void SetFont(Font &font);
virtual void Create(Window &parent, int ctrlID, Point location_, int lineHeight_, bool unicodeMode_);
virtual void SetAverageCharWidth(int width);
virtual void SetVisibleRows(int rows);
virtual int GetVisibleRows() const;
virtual PRectangle GetDesiredRect();
virtual int CaretFromEdge();
virtual void Clear();
virtual void Append(char *s, int type = -1);
virtual int Length();
virtual void Select(int n);
virtual int GetSelection();
virtual int Find(const char *prefix);
virtual void GetValue(int n, char *value, int len);
virtual void RegisterImage(int type, const char *xpm_data);
virtual void ClearRegisteredImages();
virtual void SetDoubleClickAction(CallBackAction action, void *data) {
doubleClickAction = action;
doubleClickActionData = data;
}
virtual void SetList(const char *list, char separator, char typesep);
void Draw(DRAWITEMSTRUCT *pDrawItem);
LRESULT WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam);
static LRESULT PASCAL StaticWndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam);
};
const Point ListBoxX::ItemInset(0, 0);
const Point ListBoxX::TextInset(2, 0);
const Point ListBoxX::ImageInset(1, 0);
ListBox *ListBox::Allocate() {
ListBoxX *lb = new ListBoxX();
return lb;
}
void ListBoxX::Create(Window &parent_, int ctrlID_, Point location_, int lineHeight_, bool unicodeMode_) {
parent = &parent_;
ctrlID = ctrlID_;
location = location_;
lineHeight = lineHeight_;
unicodeMode = unicodeMode_;
HWND hwndParent = reinterpret_cast<HWND>(parent->GetID());
HINSTANCE hinstanceParent = GetWindowInstance(hwndParent);
// Window created as popup so not clipped within parent client area
id = ::CreateWindowEx(
WS_EX_WINDOWEDGE, ListBoxX_ClassName, TEXT(""),
WS_POPUP | WS_THICKFRAME,
100,100, 150,80, hwndParent,
NULL,
hinstanceParent,
this);
::MapWindowPoints(hwndParent, NULL, reinterpret_cast<POINT*>(&location), 1);
}
void ListBoxX::SetFont(Font &font) {
LOGFONT lf;
if (0 != ::GetObject(font.GetID(), sizeof(lf), &lf)) {
if (fontCopy) {
::DeleteObject(fontCopy);
fontCopy = 0;
}
fontCopy = ::CreateFontIndirect(&lf);
::SendMessage(lb, WM_SETFONT, reinterpret_cast<WPARAM>(fontCopy), 0);
}
}
void ListBoxX::SetAverageCharWidth(int width) {
aveCharWidth = width;
}
void ListBoxX::SetVisibleRows(int rows) {
desiredVisibleRows = rows;
}
int ListBoxX::GetVisibleRows() const {
return desiredVisibleRows;
}
HWND ListBoxX::GetHWND() const {
return reinterpret_cast<HWND>(GetID());
}
PRectangle ListBoxX::GetDesiredRect() {
PRectangle rcDesired = GetPosition();
int rows = Length();
if ((rows == 0) || (rows > desiredVisibleRows))
rows = desiredVisibleRows;
rcDesired.bottom = rcDesired.top + ItemHeight() * rows;
int width = MinClientWidth();
HDC hdc = ::GetDC(lb);
HFONT oldFont = SelectFont(hdc, fontCopy);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -