?? icontact.cpp
字號:
+ (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, SKIN_HEADER_Y_OFFSET, 1, SKIN_HEADER_HEIGHT, SRCCOPY);
if (!bTransitioning) {
// The "back" button
if (st == stDetails) {
StretchBlt(hdc, rHeader.left, rHeader.top,
MenuBarIconWidth, HeaderHeight,
hdcSkin, 0, SKIN_HEADER_Y_OFFSET,
SKIN_MENU_BAR_ICON_WIDTH, SKIN_HEADER_HEIGHT,
SRCCOPY);
}
// The "+" to add a contact
if (st == stList && pListData != NULL && pListData->CanAdd()) {
StretchBlt(hdc,
rHeader.right - MenuBarIconWidth, rHeader.top,
MenuBarIconWidth, HeaderHeight,
hdcSkin,
SKIN_MENU_BAR_ICON_WIDTH * 4, SKIN_HEADER_Y_OFFSET,
SKIN_MENU_BAR_ICON_WIDTH, SKIN_HEADER_HEIGHT,
SRCCOPY);
}
// The "favorite YES" icon
if (st == stDetails && pListData->CanFavorite()) {
Data dItem = pListData->GetCurrentItem();
if (dItem.isFavorite) {
StretchBlt(hdc,
rHeader.right - MenuBarIconWidth, rHeader.top,
MenuBarIconWidth, HeaderHeight,
hdcSkin,
SKIN_MENU_BAR_ICON_WIDTH * 3, SKIN_HEADER_Y_OFFSET,
SKIN_MENU_BAR_ICON_WIDTH, SKIN_HEADER_HEIGHT,
SRCCOPY);
}
// The "favorite NO" icon
else {
StretchBlt(hdc,
rHeader.right - MenuBarIconWidth, rHeader.top,
MenuBarIconWidth, HeaderHeight,
hdcSkin,
SKIN_MENU_BAR_ICON_WIDTH * 2, SKIN_HEADER_Y_OFFSET,
SKIN_MENU_BAR_ICON_WIDTH, SKIN_HEADER_HEIGHT,
SRCCOPY);
}
}
}
// The title
SelectObject(hdc, PrimaryListFont);
SetBkMode(hdc, TRANSPARENT);
SetTextAlign(hdc, TA_LEFT);
SetTextColor(hdc,
NULL == pListData
? pSettings->rgbHeaderLoading
: pSettings->rgbHeader
);
if (st == stList) {
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);
}
}
//-----------------------------------------------------------------------------
// 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 + TitlebarHeight;
// Header, with the "back" button, the "favorite" button, etc.
rHeader = rScreen;
rHeader.top = rTitlebar.bottom;
rHeader.bottom = rHeader.top + HeaderHeight;
// Menu at the bottom of the screen
rMenubar = rScreen;
rMenubar.top = rMenubar.bottom - MenuBarHeight;
// 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) * DefaultItemHeight;
}
}
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 = DefaultItemHeight;
return;
}
for (int i = 0; i < count; i++) {
StartPosition[i] = c;
int h = DefaultItemHeight;
if (pListData->IsItemNewGroup(i) && pListData->GetItem(i).wcGroup) {
h += DefaultGroupHeight;
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 DefaultItemHeight
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);
}
void ParseCommandLine(HWND hWnd, LPTSTR lpCmdLine) {
const struct CmdLineArg cmdLineArgs[] = {
TEX
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -