When I was a beginner in Windows Mobile programming, even for small test I used to create a single MFC dialog-based application with one button, and put my test code in the OnLButtonDown method.
当我还是Windows Mobile编程的初学者时,即使是进行小型测试,我也曾经使用一个按钮创建了一个基于MFC对话框的应用程序,然后将测试代码放入OnLButtonDown方法中。
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.
对于Pocket PC,它在某些有时没有MFC DLL的Windows CE设备上运行良好,甚至无法启动该应用程序。 对于第一个Microsoft Smartphone,我需要使用另一个向导,另一个资源文件,特殊的控件编译定义等许多配置。
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, pre-compiled headers and other wizard generated stuff.
现在,我知道制作一个没有任何GUI或仅带有一个可以为任何Microsoft Mobile或CE平台编译且可以正常工作的消息框的小型应用程序非常容易。 它使我能够专注于研究或测试任务,而不会在GUI安排,项目配置编译定义,预编译的标头和其他向导生成的内容上浪费时间。
Here are the steps to create this smallest Windows Mobile/CE application:
以下是创建此最小的Windows Mobile / CE应用程序的步骤:
1.在VS2005中开始一个项目。 (1. Begin a project in VS2005.)
In Visual Studio, in the "File" menu choose "New" and then "Project..." (Picture 1).
在Visual Studio中,在“文件”菜单中选择“新建”,然后选择“项目...” (图1)。
![Picture 1. Begin a project in VS2005.](https://i-blog.csdnimg.cn/blog_migrate/f530c7195dec6cd636fe69ce946b298d.png)
In the wizard, in Visual C++ section choose "Smart Device" item and on this page choose "Win32 Smart Device Project" (Picture 2).
在向导的Visual C ++部分中,选择“智能设备”项,然后在此页面上选择“ Win32智能设备项目” (图2)。
![Picture 2. New Project Wizard.](https://i-blog.csdnimg.cn/blog_migrate/ee984dcf76a3962a33ba86d2698e40f2.png)
Set the solution name and press "Ok".
设置解决方案名称,然后按“确定” 。
2.智能设备项目向导。 (2. Smart Device Project Wizard.)
You see the standard wizard for the Smart Device project. Don't click on "Finish" - we need to change few default options (Picture 3).
您会看到智能设备项目的标准向导。 不要单击“完成”-我们需要更改一些默认选项(图3)。
![Picture 3. Smart Device Project Wizard.](https://i-blog.csdnimg.cn/blog_migrate/a7ad51ca406526649701475125a805d4.png)
Choose "Platforms" and add the platforms you need. I always add Windows Mobile 5 and 6 and even "old-fashion" Smartphone 2003 (Picture 4).
选择“平台”并添加所需的平台。 我总是添加Windows Mobile 5和6,甚至是“老式” Smartphone 2003(图4)。
![Picture 4. Platforms.](https://i-blog.csdnimg.cn/blog_migrate/0bcb19df120435e37dfb5b6cf25d47ad.png)
Press "Next" to go to the "Application Settings" page (Picture 5).
按“下一步”转到“应用程序设置”页面(图5)。
![Picture 5. Application Settings.](https://i-blog.csdnimg.cn/blog_migrate/09047cbd2447ea67e12bd54f332bde71.png)
Check "Empty project" checkbox and now press "Finish" (Picture 6).
选中“空项目”复选框,然后按“完成” (图6)。
![Picture 6. Application Settings. Empty project.](https://i-blog.csdnimg.cn/blog_migrate/15d25f8a78688bf14e6ca93c105358ef.png)
3.添加新项目。 (3. Add new item.)
We have the solution and the project, but there are no source code files To make one, I'm adding (Picture 7) "New Item..." to the Source Files - choose "Add" in the popup menu and "New Items..." in the next popup.
我们有解决方案和项目,但没有源代码文件要制作一个,我要在源文件中添加(图7) “ New Item ...” -在弹出菜单中选择“ Add” ,然后选择“ New”。项目...”在下一个弹出窗口中。
![Picture 7. Add new item.](https://i-blog.csdnimg.cn/blog_migrate/ca27e0817333fe958dc0f1869d9915c1.png)
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 (Picture 8).
确保在“模板”页面的“ Visual C ++”树和“ C ++文件(.cpp)”中选择了“代码”项。 设置cpp文件的名称(例如main),然后按“添加”按钮(图8)。
![Picture 8. Add new cpp-file.](https://i-blog.csdnimg.cn/blog_migrate/48b8bfe264d744ea4246d769ef97df28.png)
4.解决方案。 (4. Solution.)
Empty source file added. We need to add few lines of code (Picture 9).
添加了空的源文件。 我们需要添加几行代码(图9)。
![Picture 9. Solution.](https://i-blog.csdnimg.cn/blog_migrate/e9786e6b8fc3792cf611af67672ccef8.png)
Let's add the following source code:
让我们添加以下源代码:
#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;
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. It is "Buffer Security Check" on "Code Generation" page in C/C++ section. The value of this field should be "No (/GS-)" (Picture 10).
如果使用Pocket PC 2003,则需要在项目设置中进行一项更改。 它是C / C ++部分“代码生成”页面上的“缓冲区安全性检查” 。 该字段的值应为“ No(/ GS-)” (图片10)。
![Picture 10. Buffer security check settings for Pocket PC 2003.](https://i-blog.csdnimg.cn/blog_migrate/4f3d955a9047bf0a91f21edfa36a2622.png)
For example this program will show the memory usage:
例如,该程序将显示内存使用情况:
#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);
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;
}
![Picture 11. Running application.](https://i-blog.csdnimg.cn/blog_migrate/12b8358e55ed305b8915bcc0782f92b2.png)
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" ", 1 * 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);
}
#ifndef _WIN32_WCE
::OutputDebugStringW(szBuffer);
::OutputDebugStringW(L"\r\n");
#endif
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 with Windows Mobile 6.1.4 allowed for such small application to allocate 26,214,400 bytes.
在Windows Mobile 6 Classic模拟器上创建的日志文件将显示您可以分配将近30MB。 带有Windows Mobile 6.1.4的HTC Diamond允许此类小型应用程序分配26,214,400字节。
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.