For Pocket PC it worked fine, on some Windows CE device that, sometimes, didn’t have the MFC DLLs, this application even didn’t start. For the first Microsoft Smartphones I needed to use another wizard, another resource file, special control compilation definitions, and so, many configurations.
Now I know that it is unbelievably easy to make a small application without any GUI or just with a message box that can be compiled for any Microsoft Mobile or CE platform and simply works. It allows me to be concentrated on the research or testing task and do not waste time on GUI arrangements, and project configurations compilation definitions, precompiled headers and other wizard generated stuff.
Here are the steps to create this smallest Windows Mobile/CE application:
1. In Visual Studio, in the File menu choose “New” and then “Project…”
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5vvQ73SBbR9W6U-s_hL09eS2FBu4fLhvvurfdeiydmzhmX_F5bfLWgGeF-jVz_56CefF3I4a4W1jcdCh4YnN21gJYNjIfjN_Ff3ftHgklOUI9LZuBAE-jYtYYJAjGYgZqsx9bHVoawUE/s400/image001.jpg)
2. In the wizard, in Visual C++ section choose “Smart Device” item and on this page choose “Win32 Smart Device Project”.
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjETu0jdx4e1XcuHYThf7tT6Pf1iDZUSSkijFbnLfzpOyIC5d3Da-O_-MxHzYeq5WI3n4h7tCGg0kdR8u6m-LciFHFDF30npeZedeu4jL5UIVfccbWmJ1fkPOLgxArvlb6GCcO3C8crPVM/s400/image002.jpg)
3. Set the solution name and press “Ok”.
4. You see the standard wizard for the Smart Device project. Don’t click on “Finish” - we need to change few default options.
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2h_-qi8HzZJ5UxzKgHVKxAKIfMAUPelZBPFeuz0aFdJvAZk1Qa__xEh5gj3syePYhvxMYFzYJwLjkYXpJd5ji-JqS8zA_VdU18vyQbwdIiFhzSutEG45YLy4KB7QCL4RMbGAptuKC-ZU/s400/image003.jpg)
5. Choose Platforms and add platforms you need. I always add Windows Mobile 5 and 6 and even “old-fashion” Smartphone 2003. Press “Next” to go to the “Application Settings” page.
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimJasqSL5E-5_tY8HpAN7l9Bec348EitjhIWtO2O759tzY0_REFCXAfDBqnFirjp76HR9jO4u84pj_X49W7OmKf1EA_WwfmwdKrXhqZYL75R9AGftNTrKGXw25jrCtVTB1IIMeOIE27g8/s400/image004.jpg)
6. Check “Empty project” checkbox and now press “Finish”.
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTGAdqdazxLzUeQyafJfZ4a1M7blMLik2LLHlkpJuDOJy_3hs540qm2hgTxGFWmH8Urp6s8H5Z8x3-BE_km8c_MK9iubN4swh6iDG8udtacA4NnF0qxSvAFTZpcwFL_hWxbBgh3avwhCc/s400/image005.jpg)
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcoOIhBZFTkg1rR-5iCtAYAopAUOEnLq1T6UQt0M6HFVi26IWxYt2ODJz4E0SllgDonLj91jc_aH-W_g7mcSr_AqYCMDmPcoGVIylZjGeoOgzwFsKYn8Ixq19nB1StFra2u9Sk2xy3y3o/s400/image006.jpg)
7. We have the solution and the project, but there are no source code files. To make one, I’m adding “New Item…” to the Source Files – choose “Add” in the popup menu and “New Items…” in the next popup.
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_G-5f3ip2nF3lvgZudSnWP1z4qUF1IatT6nUBc8xrnrscAeg1QU6WUC6NWE7KFgOznzKCIB8wZ7sWE0zF4Cn9IIkgqZI8XlebXK7vpy4LJSoCMllzSj4t4-4Z4d-C7WsKkmyZrB123oo/s400/image007.jpg)
8. Be sure that you have “Code” item selected in the “Visual C++” tree and “C++ File (.cpp)” in the Templates page. Set name for the cpp-file (for example, main) and press “Add” button.
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4myhQbsSVAIZ9yrLVLRBk1JIokWA0ddjt1zx9O6wbb3htp-Vep-PciDS108WdR2frG8pW7RY9o7XQc4tSUxgxXy7OsJQLl5Nq7AJki2ZAFknnz5dAsrDmzgHN_XEuCa9pOXeUyAvBB1U/s400/image008.jpg)
9. Empty source file added. We need to add few lines of code.
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6P4uBCkQMLIx4Z1JQS2CT08xPQOzU_D5GWSC96VgYerW8cwu1VmO_7_ish_FNgfGP0wEI85-X0LF3gbpQeylvD6dyq0lvxvItF6FGf35ayDobGBtxyOLtopw7oTs0YcisUxEwcuvAryo/s400/image009.jpg)
10. Let’s add the following source code:
#define WINVER _WIN32_WCE
#include <windows.h>
HINSTANCE g_hInstance = NULL;
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPWSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
UNREFERENCED_PARAMETER(nCmdShow);
// store the hInstance in global
g_hInstance = hInstance;
return 0;
}
The code is trivial – the standard main function that does nothing, windows.h file included, and one define set WINVER _WIN32_WCE.
You can compile this code, launch the executable on your device or in emulator – the application does nothing and shows nothing. It is just a wrapper (or template) for your future test applications.
Note: if you use Pocket PC 2003, you need to make one change in the project settings.
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguZo9wANANkiCVVgC81QRGkRR2MzlHVj362tlGLW5uayX1h6xTZXgr3FZe6VVyiSRpyYClHyN-n_BebHVX3XVgX_KpT_EPxIAZfYFjlG0yqg4RVrMzXY2XTU9C4wdLPvOcNJDW0LnjlN4/s400/image010.jpg)
It is “Buffer Security Check” on “Code Generation” page in C/C++ section. The value of this field should be “No (/GS-)”
For example this program will show the memory usage:
#define WINVER _WIN32_WCE
#include <windows.h>
HINSTANCE g_hInstance = NULL;
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPWSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
UNREFERENCED_PARAMETER(nCmdShow);
// store the hInstance in global
g_hInstance = hInstance;
MEMORYSTATUS mem_status = { 0 };
GlobalMemoryStatus(&mem_status);
WCHAR szText[MAX_PATH] = { 0 };
_snwprintf(szText, MAX_PATH, L"Memory use: %d%", mem_status.dwMemoryLoad);
::MessageBox(NULL, szText, L"Test", MB_OK);
return 0;
}
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYcAWKoBLDbgTaBR21-OhmHSXYU8gEnQ2yesioOkw4lHJpM-Lr8gHvjhxkNNJJMSOIMVNxhjNHNM7dY28TJBH1rQFxUpnbubgg5YgATO2kPzUbS4jDqZ21P_kQ3FlLsH_9ztmNSDame4g/s400/image011.jpg)
If you have a simple tracer, for example, as the one below:
#ifndef _TRACER_HEADER_
#define _TRACER_HEADER_
#include <stdlib.h>
#include <wchar.h>
inline void __cdecl Tracer(LPCWSTR lpszFormat, ...)
{
va_list args;
va_start(args, lpszFormat);
int nBuf = 0;
WCHAR szBuffer[1024];
ZeroMemory(szBuffer, 1024 * sizeof(WCHAR));
nBuf = _vsnwprintf(szBuffer + nBuf, 1024, lpszFormat, args);
static HANDLE hFile = INVALID_HANDLE_VALUE;
if (hFile == INVALID_HANDLE_VALUE)
{
WCHAR szFileName[MAX_PATH];
ZeroMemory(szFileName, MAX_PATH * sizeof(WCHAR));
::GetModuleFileName(GetModuleHandle(NULL), szFileName, MAX_PATH);
int nLength = lstrlen(szFileName);
while (nLength > 0){
nLength--;
if(szFileName[nLength] == TCHAR('.'))
break;
}
szFileName[nLength + 1] = 0;
wcsncat(szFileName, L"txt", MAX_PATH - 2);
hFile = ::CreateFileW(szFileName, GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL);
if (hFile != INVALID_HANDLE_VALUE) {
DWORD nErr = GetLastError();
DWORD nWritten = 0;
SetFilePointer(hFile, 0, 0, FILE_END);
if (nErr != ERROR_ALREADY_EXISTS)
{
char szHeader[2] = { (char)0xFF, (char)0xFE };
::WriteFile(hFile, szHeader, 2, &nWritten, NULL);
}
::WriteFile(hFile, L" ", 5 * sizeof(WCHAR), &nWritten, NULL);
WCHAR sz[2] = { WCHAR(13), WCHAR(10) };
::WriteFile(hFile, sz, 4, &nWritten, NULL);
}
}
if (hFile != INVALID_HANDLE_VALUE)
{
DWORD nLength = wcslen(szBuffer) * sizeof(WCHAR);
DWORD nWritten = 0;
::WriteFile(hFile, szBuffer, nLength, &nWritten, NULL);
WCHAR sz[2] = { WCHAR(13), WCHAR(10) };
::WriteFile(hFile, sz, 4, &nWritten, NULL);
FlushFileBuffers(hFile);
}
va_end(args);
}
#endif
you can use it instead of the message box. For example, the following code will detect how many memory you can allocate on your device with function malloc():
#define WINVER _WIN32_WCE
#include <windows.h>
#include "tracer.h"
HINSTANCE g_hInstance = NULL;
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPWSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
UNREFERENCED_PARAMETER(nCmdShow);
// store the hInstance in global
g_hInstance = hInstance;
MEMORYSTATUS mem_status = { 0 };
GlobalMemoryStatus(&mem_status);
Tracer(L"Total physical memory %d\n", mem_status.dwTotalPhys);
Tracer(L"Memory usage %d\n", mem_status.dwMemoryLoad);
LPVOID p = NULL;
DWORD nDelta = 1024 * 1024;
DWORD nSize = 0;
do
{
if (p != NULL)
{
free(p);
p = NULL;
}
nSize += nDelta;
p = malloc(nSize);
if (p != NULL)
Tracer(L"p= %p, %d bytes allocated\n", p, nSize);
} while(p != NULL);
if (p != NULL)
{
free(p);
p = NULL;
}
return 0;
}
The log-file made on the Windows Mobile 6 Classic emulator will show that you can allocate almost 30MB. HTC Diamond allowed for such small application to allocate 26,214,400 bytes. Please do not test this code under Windows CE 6.0 – the memory management changed in this version and this code may cause a problem.
In EE: "Small Windows Mobile/CE application for debug or test purpose"
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqdZamKkqcmfE2wwbtSeSt6vmjGplqYQAVpy4_GgjWr2Xk2xp9WZnWUp25ilXkthgP3DgjnKW9u_GadtgiLapxS0tI_Ci97ywSzP3ysS5f0auEbFEAHGOXwPbhJG7G1SZhDdicmyXeguA/s400/EE+Pavel+Gnatyuk+MS+Visual+C%2B%2B.png)
No comments:
Post a Comment