📄 platwin.cxx
字号:
lb = ::GetWindow(reinterpret_cast<HWND>(id), GW_CHILD);
}
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;
}
PRectangle ListBoxX::GetDesiredRect() {
PRectangle rcDesired = GetPosition();
int itemHeight = ::SendMessage(lb, LB_GETITEMHEIGHT, 0, 0);
int rows = Length();
if ((rows == 0) || (rows > desiredVisibleRows))
rows = desiredVisibleRows;
// The +6 allows for borders
rcDesired.bottom = rcDesired.top + 6 + itemHeight * rows;
int width = maxItemCharacters;
if (width < 12)
width = 12;
rcDesired.right = rcDesired.left + width * (aveCharWidth+aveCharWidth/3);
if (Length() > rows)
rcDesired.right += ::GetSystemMetrics(SM_CXVSCROLL);
rcDesired.right += IconWidth();
return rcDesired;
}
int ListBoxX::IconWidth() {
return xset.GetWidth() + 2;
}
int ListBoxX::CaretFromEdge() {
return 4 + IconWidth();
}
void ListBoxX::Clear() {
::SendMessage(lb, LB_RESETCONTENT, 0, 0);
maxItemCharacters = 0;
ltt.Clear();
}
void ListBoxX::Append(char *s, int type) {
::SendMessage(lb, LB_ADDSTRING, 0, reinterpret_cast<LPARAM>(s));
unsigned int len = static_cast<unsigned int>(strlen(s));
if (maxItemCharacters < len)
maxItemCharacters = len;
int count = ::SendMessage(lb, LB_GETCOUNT, 0, 0);
ltt.Add(count-1, type);
}
int ListBoxX::Length() {
return ::SendMessage(lb, LB_GETCOUNT, 0, 0);
}
void ListBoxX::Select(int n) {
::SendMessage(lb, LB_SETCURSEL, n, 0);
}
int ListBoxX::GetSelection() {
return ::SendMessage(lb, LB_GETCURSEL, 0, 0);
}
int ListBoxX::Find(const char *prefix) {
return ::SendMessage(lb, LB_FINDSTRING, static_cast<WPARAM>(-1),
reinterpret_cast<LPARAM>(prefix));
}
void ListBoxX::GetValue(int n, char *value, int len) {
int lenText = ::SendMessage(lb, LB_GETTEXTLEN, n, 0);
if ((len > 0) && (lenText > 0)){
char *text = new char[len+1];
if (text) {
::SendMessage(lb, LB_GETTEXT, n, reinterpret_cast<LPARAM>(text));
strncpy(value, text, len);
value[len-1] = '\0';
delete []text;
} else {
value[0] = '\0';
}
} else {
value[0] = '\0';
}
}
void ListBoxX::Sort() {
// Windows keeps sorted so no need to sort
}
void ListBoxX::RegisterImage(int type, const char *xpm_data) {
xset.Add(type, xpm_data);
}
void ListBoxX::ClearRegisteredImages() {
xset.Clear();
}
void ListBoxX::Draw(DRAWITEMSTRUCT *pDrawItem) {
if ((pDrawItem->itemAction == ODA_SELECT) || (pDrawItem->itemAction == ODA_DRAWENTIRE)) {
char text[1000];
int len = ::SendMessage(pDrawItem->hwndItem, LB_GETTEXTLEN, pDrawItem->itemID, 0);
if (len < static_cast<int>(sizeof(text))) {
::SendMessage(pDrawItem->hwndItem, LB_GETTEXT, pDrawItem->itemID, reinterpret_cast<LPARAM>(text));
} else {
len = 0;
text[0] = '\0';
}
int pixId = ltt.Get(pDrawItem->itemID);
XPM *pxpm = xset.Get(pixId);
if (pDrawItem->itemState & ODS_SELECTED) {
::SetBkColor(pDrawItem->hDC, ::GetSysColor(COLOR_HIGHLIGHT));
::SetTextColor(pDrawItem->hDC, ::GetSysColor(COLOR_HIGHLIGHTTEXT));
} else {
::SetBkColor(pDrawItem->hDC, ::GetSysColor(COLOR_WINDOW));
::SetTextColor(pDrawItem->hDC, ::GetSysColor(COLOR_WINDOWTEXT));
}
int widthPix = xset.GetWidth() + 2;
if (unicodeMode) {
wchar_t tbuf[MAX_US_LEN];
int tlen = UCS2FromUTF8(text, len, tbuf, sizeof(tbuf)/sizeof(wchar_t)-1);
tbuf[tlen] = L'\0';
::ExtTextOutW(pDrawItem->hDC, pDrawItem->rcItem.left+widthPix+1, pDrawItem->rcItem.top,
ETO_OPAQUE, &(pDrawItem->rcItem), tbuf, tlen, NULL);
} else {
::ExtTextOut(pDrawItem->hDC, pDrawItem->rcItem.left+widthPix+1, pDrawItem->rcItem.top,
ETO_OPAQUE, &(pDrawItem->rcItem), text,
len, NULL);
}
if (pxpm) {
Surface *surfaceItem = Surface::Allocate();
if (surfaceItem) {
surfaceItem->Init(pDrawItem->hDC);
//surf->SetUnicodeMode(unicodeMode);
//surf->SetDBCSMode(codePage);
int left = pDrawItem->rcItem.left;
PRectangle rc(left + 1, pDrawItem->rcItem.top,
left + 1 + widthPix, pDrawItem->rcItem.bottom);
pxpm->Draw(surfaceItem, rc);
delete surfaceItem;
::SetTextAlign(pDrawItem->hDC, TA_TOP);
}
}
if (pDrawItem->itemState & ODS_SELECTED) {
::DrawFocusRect(pDrawItem->hDC, &(pDrawItem->rcItem));
}
}
}
long ListBoxX::WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam) {
switch (iMessage) {
case WM_CREATE: {
HWND parent = ::GetParent(hWnd);
HINSTANCE hinstanceParent = GetWindowInstance(parent);
CREATESTRUCT *pCreate = reinterpret_cast<CREATESTRUCT *>(lParam);
::CreateWindowEx(
WS_EX_WINDOWEDGE, "listbox", "",
WS_CHILD | WS_VSCROLL | WS_VISIBLE |
LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_NOTIFY,
0, 0, 150,80, hWnd,
pCreate->hMenu,
hinstanceParent,
0);
}
break;
case WM_SIZE: {
HWND lb = ::GetWindow(hWnd, GW_CHILD);
::SetWindowPos(lb, 0, 0,0, LOWORD(lParam), HIWORD(lParam), 0);
}
break;
case WM_PAINT: {
PAINTSTRUCT ps;
::BeginPaint(hWnd, &ps);
::EndPaint(hWnd, &ps);
}
break;
case WM_COMMAND: {
HWND parent = ::GetParent(hWnd);
::SendMessage(parent, iMessage, wParam, lParam);
}
break;
case WM_MEASUREITEM: {
MEASUREITEMSTRUCT *pMeasureItem = reinterpret_cast<MEASUREITEMSTRUCT *>(lParam);
pMeasureItem->itemHeight = lineHeight;
if (pMeasureItem->itemHeight < static_cast<unsigned int>(xset.GetHeight())) {
pMeasureItem->itemHeight = xset.GetHeight();
}
}
break;
case WM_DRAWITEM:
Draw(reinterpret_cast<DRAWITEMSTRUCT *>(lParam));
break;
case WM_DESTROY:
::SetWindowLong(hWnd, 0, 0);
return ::DefWindowProc(hWnd, iMessage, wParam, lParam);
default:
return ::DefWindowProc(hWnd, iMessage, wParam, lParam);
}
return 0;
}
long PASCAL ListBoxX::StaticWndProc(
HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam) {
if (iMessage == WM_CREATE) {
CREATESTRUCT *pCreate = reinterpret_cast<CREATESTRUCT *>(lParam);
SetWindowPointer(hWnd, pCreate->lpCreateParams);
}
// Find C++ object associated with window.
ListBoxX *lbx = reinterpret_cast<ListBoxX *>(PointerFromWindow(hWnd));
if (lbx) {
return lbx->WndProc(hWnd, iMessage, wParam, lParam);
} else {
return ::DefWindowProc(hWnd, iMessage, wParam, lParam);
}
}
static bool ListBoxX_Register() {
WNDCLASSEX wndclassc;
wndclassc.cbSize = sizeof(wndclassc);
wndclassc.style = CS_GLOBALCLASS | CS_HREDRAW | CS_VREDRAW;
wndclassc.cbClsExtra = 0;
wndclassc.cbWndExtra = sizeof(ListBoxX *);
wndclassc.hInstance = hinstPlatformRes;
wndclassc.hIcon = NULL;
wndclassc.hbrBackground = NULL;
wndclassc.lpszMenuName = NULL;
wndclassc.lpfnWndProc = ListBoxX::StaticWndProc;
wndclassc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
wndclassc.lpszClassName = ListBoxX_ClassName;
wndclassc.hIconSm = 0;
return ::RegisterClassEx(&wndclassc) != 0;
}
bool ListBoxX_Unregister() {
return ::UnregisterClass(ListBoxX_ClassName, hinstPlatformRes) != 0;
}
Menu::Menu() : id(0) {
}
void Menu::CreatePopUp() {
Destroy();
id = ::CreatePopupMenu();
}
void Menu::Destroy() {
if (id)
::DestroyMenu(reinterpret_cast<HMENU>(id));
id = 0;
}
void Menu::Show(Point pt, Window &w) {
::TrackPopupMenu(reinterpret_cast<HMENU>(id),
0, pt.x - 4, pt.y, 0,
reinterpret_cast<HWND>(w.GetID()), NULL);
Destroy();
}
static bool initialisedET = false;
static bool usePerformanceCounter = false;
static LARGE_INTEGER frequency;
ElapsedTime::ElapsedTime() {
if (!initialisedET) {
usePerformanceCounter = ::QueryPerformanceFrequency(&frequency) != 0;
initialisedET = true;
}
if (usePerformanceCounter) {
LARGE_INTEGER timeVal;
::QueryPerformanceCounter(&timeVal);
bigBit = timeVal.HighPart;
littleBit = timeVal.LowPart;
} else {
bigBit = clock();
}
}
double ElapsedTime::Duration(bool reset) {
double result;
long endBigBit;
long endLittleBit;
if (usePerformanceCounter) {
LARGE_INTEGER lEnd;
::QueryPerformanceCounter(&lEnd);
endBigBit = lEnd.HighPart;
endLittleBit = lEnd.LowPart;
LARGE_INTEGER lBegin;
lBegin.HighPart = bigBit;
lBegin.LowPart = littleBit;
double elapsed = lEnd.QuadPart - lBegin.QuadPart;
result = elapsed / static_cast<double>(frequency.QuadPart);
} else {
endBigBit = clock();
endLittleBit = 0;
double elapsed = endBigBit - bigBit;
result = elapsed / CLOCKS_PER_SEC;
}
if (reset) {
bigBit = endBigBit;
littleBit = endLittleBit;
}
return result;
}
class DynamicLibraryImpl : public DynamicLibrary {
protected:
HMODULE h;
public:
DynamicLibraryImpl(const char *modulePath) {
h = ::LoadLibrary(modulePath);
}
virtual ~DynamicLibraryImpl() {
if (h != NULL)
::FreeLibrary(h);
}
// Use GetProcAddress to get a pointer to the relevant function.
virtual Function FindFunction(const char *name) {
if (h != NULL) {
return static_cast<Function>(
(void *)(::GetProcAddress(h, name)));
} else
return NULL;
}
virtual bool IsValid() {
return h != NULL;
}
};
DynamicLibrary *DynamicLibrary::Load(const char *modulePath) {
return static_cast<DynamicLibrary *>( new DynamicLibraryImpl(modulePath) );
}
ColourDesired Platform::Chrome() {
return ::GetSysColor(COLOR_3DFACE);
}
ColourDesired Platform::ChromeHighlight() {
return ::GetSysColor(COLOR_3DHIGHLIGHT);
}
const char *Platform::DefaultFont() {
return "Verdana";
}
int Platform::DefaultFontSize() {
return 8;
}
unsigned int Platform::DoubleClickTime() {
return ::GetDoubleClickTime();
}
bool Platform::MouseButtonBounce() {
return false;
}
void Platform::DebugDisplay(const char *s) {
::OutputDebugString(s);
}
bool Platform::IsKeyDown(int key) {
return (::GetKeyState(key) & 0x80000000) != 0;
}
long Platform::SendScintilla(WindowID w, unsigned int msg, unsigned long wParam, long lParam) {
return ::SendMessage(reinterpret_cast<HWND>(w), msg, wParam, lParam);
}
long Platform::SendScintillaPointer(WindowID w, unsigned int msg, unsigned long wParam, void *lParam) {
return ::SendMessage(reinterpret_cast<HWND>(w), msg, wParam,
reinterpret_cast<LPARAM>(lParam));
}
bool Platform::IsDBCSLeadByte(int codePage, char ch) {
return ::IsDBCSLeadByteEx(codePage, ch) != 0;
}
int Platform::DBCSCharLength(int codePage, const char *s) {
return (::IsDBCSLeadByteEx(codePage, s[0]) != 0) ? 2 : 1;
}
int Platform::DBCSCharMaxLength() {
return 2;
}
// These are utility functions not really tied to a platform
int Platform::Minimum(int a, int b) {
if (a < b)
return a;
else
return b;
}
int Platform::Maximum(int a, int b) {
if (a > b)
return a;
else
return b;
}
//#define TRACE
#ifdef TRACE
void Platform::DebugPrintf(const char *format, ...) {
char buffer[2000];
va_list pArguments;
va_start(pArguments, format);
vsprintf(buffer,format,pArguments);
va_end(pArguments);
Platform::DebugDisplay(buffer);
}
#else
void Platform::DebugPrintf(const char *, ...) {
}
#endif
static bool assertionPopUps = true;
bool Platform::ShowAssertionPopUps(bool assertionPopUps_) {
bool ret = assertionPopUps;
assertionPopUps = assertionPopUps_;
return ret;
}
void Platform::Assert(const char *c, const char *file, int line) {
char buffer[2000];
sprintf(buffer, "Assertion [%s] failed at %s %d", c, file, line);
if (assertionPopUps) {
int idButton = ::MessageBox(0, buffer, "Assertion failure",
MB_ABORTRETRYIGNORE|MB_ICONHAND|MB_SETFOREGROUND|MB_TASKMODAL);
if (idButton == IDRETRY) {
::DebugBreak();
} else if (idButton == IDIGNORE) {
// all OK
} else {
abort();
}
} else {
strcat(buffer, "\r\n");
Platform::DebugDisplay(buffer);
abort();
}
}
int Platform::Clamp(int val, int minVal, int maxVal) {
if (val > maxVal)
val = maxVal;
if (val < minVal)
val = minVal;
return val;
}
void Platform_Initialise(void *hInstance) {
OSVERSIONINFO osv = {sizeof(OSVERSIONINFO),0,0,0,0,""};
::GetVersionEx(&osv);
onNT = osv.dwPlatformId == VER_PLATFORM_WIN32_NT;
::InitializeCriticalSection(&crPlatformLock);
hinstPlatformRes = reinterpret_cast<HINSTANCE>(hInstance);
ListBoxX_Register();
}
void Platform_Finalise() {
ListBoxX_Unregister();
::DeleteCriticalSection(&crPlatformLock);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -