Pages

Friday, November 13, 2009

Motorola ожидает продать 100,000 телефонов Droid уже в ближайшие выходные, 1 миллион к концу года и 10 миллионов в следующем году.

Эта информация взята с AppleInsider:

Motorola Droid estimated to have sold 100,000 in first weekend

Verizon уже распродал половину 200,000 партии. Аналитики утверждают, что спрос только растет.

Для сравнения Apple продал более 3 миллионов своих 3GS телефонов в первые 3 дня. В следующем году ожидают 36 миллионов проданных iPhone.

Thursday, November 12, 2009

Wednesday, November 11, 2009

Test post from Windows Live Writer

It is a test. Now, the application looks great.

It works. Even from Beijing. :)

Beijing. The map added  with Windows Live Writer

Tuesday, November 10, 2009

String to double

Probably, the C++ standard library is unlimited. There are so many functions I've never heard about. For example, only today I found out that there is strtod function:

C: strtod in stdlib.h
C++: strtod in cstdlib

I knew about atof.

But this function does not work with the strings like "20nn". So, for example, how to check if this conatins a valid double?

I made even a function and tested it in this code:
#include <cstdio>
#include <string>

bool is_valid_double(const char* str)
{
while (str && *str && *str == ' ')
str++;

if (*str && *str == '-')
str++;

while (str && *str)
{
if (!isdigit(*str) && (*str != '.'))
{
if (*str == ' ')
{
while (str && *str && *str == ' ')
str++;
if (!*str)
return true;
}
return false;
}
str++;
}

return true;
}

int main()
{
char sz[16] = { 0 };
sprintf(sz, "%f", 20.0);
bool b = is_valid_double(sz);

strcpy(sz, " 20.00");
b = is_valid_double(sz);

strcpy(sz, " 20.00 ");
b = is_valid_double(sz);

strcpy(sz, " -20.00 ");
b = is_valid_double(sz);

strcpy(sz, " --20.00");
b = is_valid_double(sz);

strcpy(sz, " 20.00 2");
b = is_valid_double(sz);

strcpy(sz, " 20nn ");
b = is_valid_double(sz);

return 0;
}
And then I see (thanks to EE), that there are a set of functions such as strtod, strtof, etc. Actually, I knew about strtol, so I could guess that should be also strtod. But I didn't. :)

Window with a predefined client rectangle

The task was to make a window with an image in the background and do not stretch the image.

The first application version I made just loaded the image into the memory, detected its size and created a popup window (WS_POPUP style) exactly of this size.

The QA said that it will be good, if the window will be moveable and sizeable. Ok. I added a caption and a frame. Now the image in the background is streched.

The first solution I found in Google - detect Window rectangle, then the client rectangle and the difference should be taken into a account when I set a rectangle for MoveWindow function:
HDC hDC = ::GetDC(NULL);
const int w = GetDeviceCaps(hDC, HORZRES);
const int h = GetDeviceCaps(hDC, VERTRES);
::ReleaseDC(NULL, hDC);

RECT rcClient, rcWindow;
GetClientRect(&rcClient);
GetWindowRect(&rcWindow);
m_Diff.x = (rcWindow.right - rcWindow.left) - rcClient.right;
m_Diff.y = (rcWindow.bottom - rcWindow.top) - rcClient.bottom;
cx += m_Diff.x;
cy += m_Diff.y;

RECT rect;
rect.left = (w >> 1) - (cx >> 1);
rect.top = (h >> 1) - (cy >> 1);
rect.right = rect.left + cx;
rect.bottom = rect.top + cy;

MoveWindow(&rect);
Two variables cx and cy are the predefined size of the background image.

This code works. But something's wrong here. Let's use Google again. :)

Of course, there is a Win32 API function that does the job: AdjustWindowRectEx.

And here is the code:
BOOL Center(int cx, int cy, RECT& rect)
{
HDC hDC = ::GetDC(NULL);
const int w = GetDeviceCaps(hDC, HORZRES);
const int h = GetDeviceCaps(hDC, VERTRES);
::ReleaseDC(NULL, hDC);

rect.left = (w >> 1) - (cx >> 1);
rect.top = (h >> 1) - (cy >> 1);
rect.right = rect.left + cx;
rect.bottom = rect.top + cy;

AdjustWindowRectEx(&rect, s_nWndStyle, FALSE, s_nWndStyleEx);
return TRUE;
}
This function above calculates the window rectangle for the predefined client area in the center of the desktop.
The function exists even for Windows Mobile and Windows CE: AdjustWindowRectEx. This MSDN article contains an example.

Now if you need to control the size of your window (do not allow to be smaller or bigger than the predefined size), you need to handle WM_GETMINMAXINFO message. For example, in the ATL-based application it will look as the following:
LRESULT OnGetMinMaxInfo(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
LPMINMAXINFO pInfo = (LPMINMAXINFO)lParam;
if (pInfo != NULL)
{
pInfo->ptMinTrackSize = CPainter::GetMinSize();
}
return 0;
}
ptMinTrackSize in the MINMAXINFO structure is just a point, for example, set it as { 200, 200 } and the window cannot be smaller then 200x200.

More information about this WM_GETMINMAXINFO you can find on The Old New Thing.

Monday, November 9, 2009

The Beginning

If you are the Window programmer, you know that everything begins from here:
#define WIN32_LEAN_AND_MEAN        // Exclude rarely-used stuff from Windows headers

#include <windows.h>

LPCWSTR s_szWndClassName = L"Small Window";

ATOM RegisterWndClass(HINSTANCE hInstance, LPCWSTR lpszWndClassName);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE,
LPWSTR, int nCmdShow)
{
HWND hWnd = NULL;
MSG msg = { 0 };

RegisterWndClass(hInstance, s_szWndClassName);

hWnd = CreateWindow(s_szWndClassName, s_szWndClassName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
NULL, NULL, hInstance, NULL);

if (hWnd != NULL)
{
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);

// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

return (int)msg.wParam;
}


ATOM RegisterWndClass(HINSTANCE hInstance, LPCWSTR lpszWndClassName)
{
WNDCLASSEX wcex = { 0 };
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.hInstance = hInstance;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = lpszWndClassName;
return RegisterClassEx(&wcex);
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;

switch (message)
{
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;

case WM_DESTROY:
PostQuitMessage(0);
break;

    default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}

Do you know who's this?