📄 icontact.cpp
字号:
}
else if (dd.type == diEmail
|| dd.type == diUrl) {
SelectObject(hdc, PrimaryListFont);
SetTextAlign(hdc, TA_CENTER);
ExtTextOut(hdc, (rRow.right - rRow.left) / 2 + rRow.left,
(rRow.bottom - rRow.top - ITEM_FONT_SIZE) / 2 + rRow.top,
ETO_CLIPPED, &rClip, dd.text, _tcslen(dd.text), 0);
}
else {
SelectObject(hdc, ItemDetailsFont);
SetTextAlign(hdc, TA_RIGHT | TA_BOTTOM);
int y = (rRow.bottom - rRow.top) / 2 + rRow.top;
rClip.right = rRow.left + 49;
ExtTextOut(hdc, rRow.left + 49,
y + (ITEM_DETAILS_FONT_SIZE / 2),
ETO_CLIPPED, &rClip, dd.label, _tcslen(dd.label), NULL);
rClip.left = rClip.right + 3;
rClip.right = rRow.right - padding;
if (dd.type == diPhone) {
rClip.right -= 28;
ExtTextOut(hdc, rRow.right - 12,
y + (ITEM_DETAILS_FONT_SIZE / 2),
NULL, NULL, pSettings->sms_string,
_tcslen(pSettings->sms_string), NULL);
}
SetTextAlign(hdc, TA_LEFT | TA_BOTTOM);
SelectObject(hdc, PrimaryListFont);
ExtTextOut(hdc, rRow.left + 52, y + (ITEM_FONT_SIZE / 2),
ETO_CLIPPED, &rClip, dd.text, _tcslen(dd.text), NULL);
}
}
}
void DrawKeyboardOn(HDC hdc, RECT rKeyboard) {
SelectObject(hdc, KeyboardFont);
SelectObject(hdc, pSettings->hpenKeyboardGrid);
SetTextColor(hdc, pSettings->rgbKeyboardText);
SetBkMode(hdc, TRANSPARENT);
int x, y, g, h;
FillRect(hdc, &rKeyboard, pSettings->hbrKeyboardBackground);
SetTextAlign(hdc, TA_CENTER);
// Draw the horizontal lines
for (h = 0; h < nKeyboardRows; h++) {
y = rKeyboard.top + h
* (rKeyboard.bottom - rKeyboard.top) / nKeyboardRows;
MoveToEx(hdc, rKeyboard.left, y, (LPPOINT) NULL);
LineTo(hdc, rKeyboard.right, y);
}
MoveToEx(hdc, rKeyboard.left, rKeyboard.bottom - 1, (LPPOINT) NULL);
LineTo(hdc, rKeyboard.right, rKeyboard.bottom - 1);
// Draw the vertical lines
for (g = 0; g < nKeyboardCols; g++) {
x = rKeyboard.left + g
* (rKeyboard.right - rKeyboard.left) / nKeyboardCols;
MoveToEx(hdc, x, rKeyboard.top, (LPPOINT) NULL);
LineTo(hdc, x, rKeyboard.bottom);
}
MoveToEx(hdc, rKeyboard.right - 1, rKeyboard.top, (LPPOINT) NULL);
LineTo(hdc, rKeyboard.right - 1, rKeyboard.bottom);
// Draw the letters
int i = 0;
for (h = 0; h <= nKeyboardRows; h++) {
y = rKeyboard.top
+ ((GroupHeight - KEYBOARD_FONT_SIZE) / 2)
+ (GroupHeight * h);
for (g = 0; g < nKeyboardCols; g++) {
x = rKeyboard.left + (GroupWidth / 2) + (GroupWidth * g);
if (i < nKeyboardLetters) {
ExtTextOut(hdc, x, y, NULL, NULL, &alphabet[i++], 1, 0);
}
}
}
}
void DrawHeaderOn(HDC hdc, ScreenType st, RECT rHeader, HDC hdcSkin) {
// The background of the header bar
StretchBlt(hdc, rHeader.left, rHeader.top,
rHeader.right - rHeader.left, rHeader.bottom - rHeader.top,
hdcSkin, 0, HEADER_Y_OFFSET, 1, HEADER_HEIGHT, SRCCOPY);
if (!bTransitioning) {
// The "back" button
if (st == stDetails) {
BitBlt(hdc, rHeader.left, rHeader.top, rHeader.left + 26,
rHeader.bottom - rHeader.top,
hdcSkin, 0, HEADER_Y_OFFSET, SRCCOPY);
}
// The "+" to add a contact
if (st == stList && pListData != NULL && pListData->CanAdd()) {
BitBlt(hdc, rHeader.right - 40, rHeader.top, 40,
rHeader.bottom - rHeader.top,
hdcSkin, 192, HEADER_Y_OFFSET, SRCCOPY);
}
// The "favorite YES" icon
if (st == stDetails && pListData->CanFavorite()) {
Data dItem = pListData->GetCurrentItem();
if (dItem.isFavorite) {
BitBlt(hdc, rHeader.right - 40, rHeader.top, 40,
rHeader.bottom - rHeader.top,
hdcSkin, 144, HEADER_Y_OFFSET, SRCCOPY);
}
// The "favorite NO" icon
else {
BitBlt(hdc, rHeader.right - 40, rHeader.top, 40,
rHeader.bottom - rHeader.top,
hdcSkin, 96, HEADER_Y_OFFSET, SRCCOPY);
}
}
}
// The title
SelectObject(hdc, PrimaryListFont);
SetBkMode(hdc, TRANSPARENT);
SetTextAlign(hdc, TA_LEFT);
if (st == stList) {
SetTextColor(hdc,
NULL == pListData
? pSettings->rgbHeaderLoading
: pSettings->rgbHeader
);
DrawText(hdc,
( nCurrentTab == 0 ? pSettings->favorite_category
: nCurrentTab == 1 ? pSettings->recents_string
: pSettings->allcontacts_string),
-1, &rHeader, DT_CENTER | DT_VCENTER
);
}
else if (st == stDetails) {
DrawText(hdc, pListData->GetCurrentDetailTitle(),
-1, &rHeader, DT_CENTER | DT_VCENTER);
}
/* DrawText(hdc,
( nCurrentTab == 0 ? pSettings->favorite_category
: nCurrentTab == 1 ? pSettings->recents_string
: st == stList ? pSettings->allcontacts_string
: pSettings->details_string
),
}
*/
}
//-----------------------------------------------------------------------------
// Utility functions
//
void InitSurface(HWND hWnd) {
HRESULT hr = S_OK;
HDC hdc;
hdc = GetDC(hWnd);
// Update the RECTs for the individual sections
GetClientRect(hWnd, &rScreen);
nScreenHeight = rScreen.bottom - rScreen.top;
int nScreenWidth = rScreen.right - rScreen.left;
// Title bar, with date, carrier, battery, signal strength, etc.
rTitlebar = rScreen;
rTitlebar.bottom = rTitlebar.top + TITLE_BAR_HEIGHT;
// Header, with the "back" button, the "favorite" button, etc.
rHeader = rScreen;
rHeader.top = rTitlebar.bottom;
rHeader.bottom = rHeader.top + HEADER_HEIGHT;
// Menu at the bottom of the screen
rMenubar = rScreen;
rMenubar.top = rMenubar.bottom - MENU_BAR_HEIGHT;
// From the header to the bottom of the screen
rContent = rScreen;
rContent.top = rHeader.bottom;
// Between the header and the menu bar
rList = rContent;
rList.bottom = rMenubar.top;
rListHeight = rList.bottom - rList.top;
// Calculate how many rows / cols for the keyboard
double screenRatio = (double)nScreenWidth / nScreenHeight;
nKeyboardRows = 1;
nKeyboardCols = 1;
while (nKeyboardRows * nKeyboardCols < nKeyboardLetters) {
if (nScreenWidth < nScreenHeight) {
nKeyboardRows = (int)(++nKeyboardCols / screenRatio);
}
else {
nKeyboardCols = (int)(++nKeyboardRows * screenRatio);
}
}
if (nScreenWidth < nScreenHeight) {
while ((nKeyboardRows - 1) * nKeyboardCols >= nKeyboardLetters) {
nKeyboardRows--;
}
}
else {
while (nKeyboardRows * (nKeyboardCols - 1) >= nKeyboardLetters) {
nKeyboardCols--;
}
}
GroupWidth = nScreenWidth / nKeyboardCols;
GroupHeight = nScreenHeight / nKeyboardRows;
// Initialize the DCs and Bitmaps
if (hdcMem)
CBR(DeleteDC(hdcMem));
hdcMem = CreateCompatibleDC(hdc);
if (hbmMem)
CBR(DeleteObject(hbmMem));
hbmMem = CreateCompatibleBitmap(hdc, nScreenWidth, nScreenHeight);
SelectObject(hdcMem, hbmMem);
if (hdcTmp)
CBR(DeleteDC(hdcTmp));
hdcTmp = CreateCompatibleDC(hdc);
if (hbmTmp)
CBR(DeleteObject(hbmTmp));
hbmTmp = CreateCompatibleBitmap(hdc, nScreenWidth, nScreenHeight);
SelectObject(hdcTmp, hbmTmp);
if (hdcPage1)
CBR(DeleteDC(hdcPage1));
hdcPage1 = CreateCompatibleDC(hdc);
if (hbmPage1)
CBR(DeleteObject(hbmPage1));
hbmPage1 = CreateCompatibleBitmap(hdc, nScreenWidth, nScreenHeight);
SelectObject(hdcPage1, hbmPage1);
if (hdcPage2)
CBR(DeleteDC(hdcPage2));
hdcPage2 = CreateCompatibleDC(hdc);
if (hbmPage2)
CBR(DeleteObject(hbmPage2));
hbmPage2 = CreateCompatibleBitmap(hdc, nScreenWidth, nScreenHeight);
SelectObject(hdcPage2, hbmPage2);
// Calculate skin filename
if (!hbmSkin) {
TCHAR szSkinFileName[MAX_PATH];
GetModuleFileName(NULL, szSkinFileName, MAX_PATH);
TCHAR * pstr = _tcsrchr(szSkinFileName, '\\');
if (pstr) *(++pstr) = '\0';
StringCchCat(szSkinFileName, MAX_PATH, pSettings->skin_name);
StringCchCat(szSkinFileName, MAX_PATH, TEXT(".png"));
hbmSkin = SHLoadImageFile(szSkinFileName);
// Load skin
hdcSkin = CreateCompatibleDC(hdc);
SelectObject(hdcSkin, hbmSkin);
}
CBR(ReleaseDC(hWnd, hdc));
Error:
ASSERT(SUCCEEDED(hr));
}
void CalculateHeights() {
int c = 0;
TCHAR letter[2];
TCHAR * pdest;
int index;
letter[1] = 0;
int count = 0;
if (stScreenType == stDetails) {
if (NULL != pListData) {
count = pListData->GetItemDetailCount();
c = (count - 1) * DEFAULT_ITEM_HEIGHT;
}
}
else {
if (NULL != pListData)
count = pListData->GetItemCount();
nKeyboardLetters = _tcslen(pSettings->alphabet);
bool bAutoAlphabet = nKeyboardLetters == 0;
StringCchCopy(alphabet, ALPHABET_MAX_SIZE, pSettings->alphabet);
for (int i = 0; i < ALPHABET_MAX_SIZE; i++) {
GroupPosition[i] = -1;
StartPosition[i] = 0;
}
if (count == 0) {
ListHeight = 0;
AverageItemHeight = DEFAULT_ITEM_HEIGHT;
return;
}
for (int i = 0; i < count; i++) {
StartPosition[i] = c;
int h = DEFAULT_ITEM_HEIGHT;
if (pListData->IsItemNewGroup(i) && pListData->GetItem(i).wcGroup) {
h += DEFAULT_GROUP_HEIGHT;
letter[0] = pListData->GetItem(i).wcGroup;
pdest = wcsstr(pSettings->alphabet, letter);
index = (int)(pdest - pSettings->alphabet);
if (index >= 0 && index < ALPHABET_MAX_SIZE) {
GroupPosition[index] = c;
}
else if (bAutoAlphabet && nKeyboardLetters < ALPHABET_MAX_SIZE) {
GroupPosition[nKeyboardLetters] = c;
alphabet[nKeyboardLetters] = letter[0];
nKeyboardLetters++;
}
}
c += h;
}
if (GroupPosition[0] == -1)
GroupPosition[0] = 0;
for (int i = 1; i < ALPHABET_MAX_SIZE; i++) {
if (GroupPosition[i] == -1)
GroupPosition[i] = GroupPosition[i-1];
}
StartPosition[count] = c;
}
ListHeight = c;
AverageItemHeight = ListHeight / count;
}
int GetPixelToItem(int y) {
y = min(ListHeight - 1, y);
y = max(0, y);
// estimate based on DEFAULT_ITEM_HEIGHT
int guess = y / AverageItemHeight;
int max = NULL == pListData ? 0 : pListData->GetItemCount();
if (guess > max)
guess = max;
while (y < StartPosition[guess] && guess > 0) {guess--;}
while (y >= StartPosition[guess+1] && guess < max) {guess++;}
return guess;
}
void ScrollBar(int y) {
bScrolling = true;
Velocity = 20;
int maxScrolled = ListHeight <= rListHeight ? 0 : ListHeight - rListHeight;
// if "Contacts", scroll by chunks of A,B,C,etc.
if (nCurrentTab == 2) {
int index = (y - rList.top) * nKeyboardLetters / rListHeight;
Scrolled = index < 0 ? 0
: index >= nKeyboardLetters ? maxScrolled
: GroupPosition[index];
}
// otherwise, just do a normal scroll
else {
double pct = (double)(y - rList.top)
/ (double)rListHeight;
Scrolled = (int)(maxScrolled * pct);
}
Scrolled = min(Scrolled, maxScrolled);
Scrolled = max(Scrolled, 0);
}
void ScrollTo(HWND hWnd, int position, int duration) {
int minScrolled = 0;
int maxScrolled = ListHeight <= rListHeight ? 0 : ListHeight - rListHeight;
if (position < minScrolled)
position = minScrolled;
if (position > maxScrolled)
position = maxScrolled;
Scroll_StartPosition = Scrolled;
Scroll_Change = position - Scroll_StartPosition;
Scroll_Duration = duration;
Scroll_StartTime = ::GetTickCount();
Scroll_TimeCounter = 0;
SetTimer(hWnd, IDT_TIMER_SCROLL_TO, REFRESH_RATE, NULL);
}
void StartTransition(HWND hWnd, TransitionType tr, int duration) {
if (tr == ttSlideLeft)
if (FAILED(pListData->PopulateDetails()))
return;
bTransitioning = true;
nTransitionDuration = duration;
dTransitionPct = 0.0;
trTransitionType = tr;
dwTransitionStart = ::GetTickCount();
InvalidateRect(hWnd, &rScreen, FALSE);
if (tr == ttSlideLeft || tr == ttSlideRight) {
if (tr == ttSlideLeft) {
ListScrolled = Scrolled;
Scrolled = 0;
}
DrawScreenOn(hdcPage1, stList, hdcTmp, rScreen, ListScrolled);
DrawScreenOn(hdcPage2, stDetails, hdcTmp, rScreen, Scrolled);
}
else if (tr == ttKeyboardExpand || tr == ttKeyboardShrink) {
DrawScreenOn(hdcPage1, stList, hdcTmp, rScreen, Scrolled);
DrawKeyboardOn(hdcPage2, rScreen);
}
SetTimer(hWnd, IDT_TIMER_TRANSITION, REFRESH_RATE, NULL);
}
void SwitchTab(HWND hWnd, int which) {
if (pListData) {
pListData->Release();
delete pListData;
}
stScreenType = stList;
nCurrentTab = which;
Scrolled = 0;
bScrolling = false;
bDragging = false;
InvalidateRect(hWnd, &rMenubar, false);
InvalidateRect(hWnd, &rHeader, false);
InvalidateRect(hWnd, &rList, false);
pListData = NULL;
SetTimer(hWnd, IDT_TIMER_LOADLIST, REFRESH_RATE, NULL);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -