Resolution-Aware CAB on Windows Mobile

  • GetSystemMetrics or GetDeviceCaps inside a CAB’s Setup.dll
  • wceload.exe is not resolution- and DPI-aware
  • RESDLL SDK Sample 

Sincerely I haven’t easily found entries about this over the web, so I think it’s worth mentioning it. Maybe many know, but possible many others don’t… smile_regular Imagine you want to perform different actions during install depending on the device’s resolution. A possible code to retrieve resolution can use GetSystemMetrics or GetDeviceCaps. My troubleshooting, as initial step, was as usual to verify if I could reproduce ISV’s problem, even on Device Emulator (thus avoiding possible problems related to OEMs’ customizations). So I included the following in a CAB’s Setup.dll’s Install_Init (Install_Exit is the same):

         HRESULT hr = S_OK;

        LPTSTR pszBuf = new TCHAR[256];
        ZeroMemory(pszBuf, 255);

        int X = GetSystemMetrics(SM_CXSCREEN);
        int Y = GetSystemMetrics(SM_CYSCREEN);

        hr = StringCchPrintf(pszBuf, 
                        LocalSize(pszBuf) / sizeof(TCHAR),
                        TEXT("X: %d\r\nY: %d"), 
                        X, Y);
        CHR(hr);

        MessageBox(hwndParent, pszBuf, TEXT("Install_Exit"), MB_OK);

    Exit:
        return codeINSTALL_INIT_CONTINUE; //or codeINSTALL_EXIT_DONE for Install_Exit

Specifically:

  • on a VGA WM6 Emulator (640x480) it returned 320x240
  • on a square VGA WM6 Emulator (480x480) it returned 240x240
  • on a square QVGA WM6 Emulator (320x320) it returned 240x240
  • on a WM6.1.4 EMULATOR (480x800) it returned 240x400

When using precisely the same code in a Win32 Smart Device Console application, the values returned were the expected ones…

After working with a colleague (thanks Manfred! smile_regular) I got the confirmation about an idea… the problem here is that a CAB’s Setup.dll gets loaded by wceload.exe when installing the CAB, and wceload.exe is not resolution- and DPI-aware . Therefore when setup.dll’s code runs inside the wceload’s context it can’t successfully call GetSystemMetrics or also GetDeviceCaps.

It turned out that to address this limitation, a sample is provided in the SDKs explaining how to do this: "C:\Program Files (x86)\Windows Mobile 6 SDK\Samples\PocketPC\CPP\win32\resdll" (MSDN Doc here). Notice that setup.dll’s Install_Exit\_Init containing code to run an external DPI-aware application, whose sample code is also provided.

Cheers,

~raffaele