Thursday, October 9, 2008

Oriented Dialogs and SP platform

Some new SP devices supports screen rotation (ex: HTC S7xx series) but all 'CStdOrientedDialog' classes are only supported for PPC platform in WTL8.0.
So i changed some WTL files to add those classes to SP too.
The only file to change is: 'atlwince.h'
If you want support also in wizard you need to change also: 'AppType.htm' and 'Platforms.htm' in 'AppWizMobile\Files\HTML\1033' folder.

You can find the modified files here

Bye :)

Wednesday, October 1, 2008

CStdDialogImpl and the OK button

Are using CStdDialogImpl as the base class for your WTL dialogs? Are you having difficulty hiding the "ok" button? Here's a simple solution:

Derive your dialog class (say CMyDialog) from

CStdDialogImpl<CMyDialog, SHIDIF_SIZEDLGFULLSCREEN | SHIDIF_SIPDOWN>

On the OnInitDialog handler, call:

SHDoneButton(m_hWnd, SHDB_HIDE);
ModifyStyle(0, WS_NONAVDONEBUTTON, SWP_NOSIZE);

Make sure you change all the calls to CStdDialogImpl<CMyDialog> methods with the new base (you can use a typedef for that).

Tuesday, August 5, 2008

ClearType on a memory DC

I recently developed a small information browser application for Windows CE 5.0 devices. This small application uses a touch list as an item selector and displays an in-memory bitmap with textual information related to the selected item.

The touch list uses a ClearType-rendered font (see the latest Touch List sample) painted to a memory DC. I also used a ClearType font to paint the text on the memory bitmap containing the detailed information about the main list item. Unfortunately the font was not being rendered in ClearType mode. Why was this? Maybe a Windows CE issue?

After quickly recompiling the code to target a Windows Mobile 6.0 device, I got exactly the same result. So I turned to the rendering code looking for a bug, but found none. Instead I found an interesting difference between the touch list rendering and the bitmap rendering.

If you look at the touch list samples, you will see that the memory DC is created from a CPaintDC. On the bitmap rendering code, I was using a memory DC created from a CClientDC (got the same result by using NULL as the HDC value).

So apparently you can only render ClearType fonts to a memory DC when this is created as compatible with the DC you get on BeginPaint... Has anyone else experienced this?

Monday, August 4, 2008

Windows Mobile API Usage Tool

Microsoft has just released a new tool to determine the Windowm Mobile API usage in your application. This is especially useful for deprecated functions! Go take a look here.

Wednesday, July 2, 2008

Installing WTL Helper in VS 2008

Last April my good friend Cristiano Severini managed to recompile Sergey Solozhentsev's WTL Helper for VS 2008. He wrote a few instructions about how to do it, but they are a bit incomplete. I have just reviewed the whole process with him and managed to successfully install his version of the WTL Helper DLL on a VS 2008 under Vista. Here's how to do it:
  • Install the original WTL Helper package;
  • Download WtlHelper9.dll (1.2.8.0) and copy it to the same install directory;
  • Open a command line (use Admin rights under Vista), go to the install directory and run the regvsr32 WtlHelper9.dll command;
  • Start VS 2008 - the WTL helper must be there.
Enjoy!

Friday, June 6, 2008

Animating Child View Transitions - The article

I have just posted a new article on Code Project with the last version the the child view transition animation code. You can read the article here.

Thursday, May 29, 2008

Porting old projects to WTL8

Hi,
after upgraded to WTL 8.0 if you try to compile old project you'll get errors like these:

error C2668: 'lstrlenA' : ambiguous call to overloaded function ...\WTL80\include\atlapp.h 697
error C2514: 'size_t' : class has no constructors ...\WTL80\include\atlapp.h 73e
error C3861: 'lstrcpynA': identifier not found ...\WTL80\include\atlapp.h 74


The way to fix it is simple, just add:
#if _ATL_VER == 0x900
#define _SECURE_ATL 1
#endif

just before the include of atlapp.h

:)

Wednesday, May 28, 2008

Inject Dlls

Hi,
today i'll explain how inject dlls into another process.

To inject external dlls into the processes we need to use some functions exported from coredll.dll. These functions are documented in Platform Builder but not in SDK so we need to declare them as extern:
extern "C"
{
BOOL __stdcall SetKMode(BOOL fMode);
DWORD __stdcall SetProcPermissions(DWORD);
LPVOID __stdcall MapPtrToProcess (LPVOID lpv, HANDLE hProc);
struct CALLBACKINFO
{
HANDLE m_hDestProcess;
FARPROC m_pFunction;
PVOID m_pFirstArgument;
};
DWORD __stdcall PerformCallBack4(CALLBACKINFO *pcbi, DWORD dw1, DWORD dw2, DWORD dw3);
}


After declared the undocumented functions we need to write code to use them to inject dlls, so:

//change the kernelmode and the permission for our code
BOOL bMode = SetKMode(TRUE);
DWORD dwPerm = SetProcPermissions(0xFFFFFFFF);

CALLBACKINFO cbi;
cbi.m_hDestProcess = hProcess;
cbi.m_pFunction = (FARPROC)MapPtrToProcess(GetProcAddress(GetModuleHandle(L"COREDLL"), L"LoadLibraryW"), hProcess);
cbi.m_pFirstArgument = (LPVOID)MapPtrToProcess(lpszFullPathDll, GetCurrentProcess());
HINSTANCE hInst = (HINSTANCE)PerformCallBack4(&cbi, 0,0,0); //returns the HINSTANCE from LoadLibraryW

//restore kernelmode and permission
SetKMode(bMode);
SetProcPermissions(dwPerm);


Some details:
hProcess: is the handle of the process where the dll will be injected;
lpszFullPathDll: is the full path to the dll which must be injected;

After a dll is injected into the hProcess we can call every exported function with the same method:

//get the proc address
FARPROC pHook = GetProcAddress(hInst, (LPCTSTR)L"ExportedFunction");
cbi.m_hDestProcess = hProcess;
cbi.m_pFunction = (FARPROC)MapPtrToProcess(pHook, hProcess);
cbi.m_pFirstArgument = NULL; //here we can pass any argument for our 'ExportedFunction'
DWORD dw = PerformCallBack4(&cbi, 0, 0, 0);//returns the same value of 'ExportedFunction'


And finally, as we loaded the dll, we can unload it calling 'FreeLibrary':

cbi.m_hDestProcess = hProcess;
cbi.m_pFunction = (FARPROC)MapPtrToProcess(GetProcAddress(GetModuleHandle(L"COREDLL"), L"FreeLibrary"), hProcess);
cbi.m_pFirstArgument = hInst; //HINSTANCE returned by LoadLibrary
DWORD dw = PerformCallBack4(&cbi, 0,0,0); //returns 1 if correctly unloaded


Enjoy!
:)

Tuesday, May 27, 2008

An alternative to the SHMENUBAR resource

The SHMENUBAR resource is a pain. A real pain. Why is there no support for this on the VS 2005 / 2008 resource editor? This resource is actually quite powerful when it comes to defining the WM application menu and fine-tuning its appearance. But when you need to change something, you need to remember the string table IDs, the toolbar button options and all that.

Most WM applications I have seen so far use a popup menu attached to each of the menu bar buttons. If this is your case, you can forget about the SHMENUBAR resource and use the menu editor. Create a menu with two items and their popups on the resource editor. If you are using WTL, go to your CMainFrame::OnCreate method and instead of the simple

CreateSimpleCEMenuBar();

write:

CreateSimpleCEMenuBar(IDR_MAINFRAME, SHCMBF_HMENU);

The IDR_MAINFRAME is your main menu ID. And that's all you need.

If you are using straight API calls, when calling the SHCreateMenuBar API, make sure that the dwFlags member of the SHMENUBARINFO contains the SHCMBF_HMENU flag and that nToolbarId contains your menu ID.

Thursday, May 22, 2008

WTL - Create a dialog without resource

Hi,
yesterday i explained how create a menu by code without use resource, today i'll explain how to create a dialog without use resource using WTL in 2 mins and with 20 lines :)

WTL framework comes with two classes:
CMemDlgTemplate (which define our dialog template)
CIndirectDialogImpl (which define our dialog class)

In the code below i'll show how create an empty dialog with just few lines:


#pragma once
#include <atldlgs.h> //don't forget it :)

typedef
CWinTraits<WS_VISIBLEWS_POPUPDS_CENTER> MyDlgTraits;
class
CAboutDlg : public CIndirectDialogImpl<CAboutDlg, CMemDlgTemplate,
CStdDialogImpl<CAboutDlg>>
{
public:
//ovverride the DoInitTemplate and set the correct values for template
void
DoInitTemplate()
{
m_Template.Create(false, L"OUR DIALOG CAPTION", 0, 0, 0, 0,
MyDlgTraits::GetWndStyle(0),
MyDlgTraits::GetWndExStyle(0));
}

BEGIN_MSG_MAP(CAboutDlg)
MESSAGE_HANDLER(WM_INITDIALOG,
OnInitDialog)
CHAIN_MSG_MAP(CStdDialogImpl)
END_MSG_MAP()

LRESULT
OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL&
bHandled)
{
#ifdef
WIN32_PLATFORM_PSPC
AtlCreateEmptyMenuBar(m_hWnd);
#endif
return
bHandled = FALSE;
}
};


I used CStdDialogImpl as base class which is the specific base dialog for devices.

Bye

Wednesday, May 21, 2008

Create Menu Bar Programmatically - WM5

Hi,
today i show you how create a menubar from code without use any resource.

//add these lines in your wm_initdialog or wm_create function
#define ID_CHANGE_TEXT WM_APP+1
#define ID_ADD_NEW_ITEM WM_APP+2
#define ID_NEW_ITEM WM_APP+3

//Create the right popupmenu
HMENU hPopupRightMenu = ::CreatePopupMenu();
::InsertMenu(hPopupRightMenu, -1, MF_BYPOSITION, ID_CHANGE_TEXT, L"Change Left Text");
::InsertMenu(hPopupRightMenu, -1, MF_BYPOSITION, ID_ADD_NEW_ITEM, L"Add New Item here");
//create the toolbar menu
HMENU hMenu = ::CreateMenu();
::InsertMenu(hMenu, 0, MF_BYPOSITION, IDOK, L"Left");
::InsertMenu(hMenu, 1, MF_BYPOSITIONMF_POPUP, (UINT)hPopupRightMenu, L"Right");
//and now create the menu bar
HWND hMB = AtlCreateMenuBar(m_hWnd, (UINT)hMenu, SHCMBF_HMENU);

now add handlers for our menus id:
LRESULT OnChangeText(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
//try to modify text on the left button
TBBUTTONINFO tbbit = {0};
tbbit.cbSize = sizeof(tbbit);
tbbit.dwMask = TBIF_TEXT;
tbbit.pszText = L"Exit";
::SendMessage (SHFindMenuBar(m_hWnd), TB_SETBUTTONINFO, (UINT)IDOK, (LPARAM)&tbbit);
return 0;
}

LRESULT OnAddNewItem(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
//now try to modify right popup
TBBUTTONINFO tbbi = {0};
tbbi.cbSize = sizeof(tbbi);
tbbi.dwMask = TBIF_LPARAM;
::SendMessage (SHFindMenuBar(m_hWnd), TB_GETBUTTONINFO, (WPARAM)0, (LPARAM)&tbbi);
HMENU hPopupMenu = (HMENU)tbbi.lParam;
InsertMenu(hPopupMenu, -1, MF_BYPOSITION, ID_NEW_ITEM, L"New Item!");
return 0;
}

LRESULT OnNewItem(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
MessageBox(L"New Item Clicked!!!");
return 0;
}


this is ... :)

Tuesday, May 20, 2008

POOM: 'unresolved external symbol' or 'already defined'

Often when we use POOM api's we get those errors by compiler.
We have two methods to fix it:

solution a
- include only where you need;
- include into only one .cpp file:
#define INITGUID
#include <initguid.h>
#include <pimstore.h>
#pragma comment(lib, "pimstore.lib") //don't forget to link library ;)


solution b
- include where you need:
#include <pimstore.h>
#pragma comment(lib, "pimstore.lib") //don't forget to link library ;)

- replace the IID_* and CLSID_* with the __uuidof([interface]) sentence
so:
CLSID_Application ==> __uuidof(Application)
IID_IItem ==> __uuidof(IItem)
IID_IPOutlookApp ==> __uuidof(IPOutlookApp)
and so on...



I hope this help you

Thursday, May 15, 2008

Welcome

Welcome to the Windows Mobile Developers Blog!