65.9K
CodeProject 正在变化。 阅读更多。
Home

Windows Mobile(WinCE)的轻量级图像查看器

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.13/5 (8投票s)

2007年11月23日

CPOL

5分钟阅读

viewsIcon

47252

downloadIcon

1539

演示如何在 Pocket PC 屏幕上显示任何大小的 BMP 或 JPEG 图像并滚动到其极限

Screenshot - wmimgvwr_01.jpg

引言

本文旨在解释为 Pocket PC 编码图像查看器的原理。该示例应用程序很简单。没有缩放或旋转图像等高级功能。事实上,示例中我只想解释 3 个要点

  1. 如何将窗口切换到全屏模式。
  2. 如何加载 JPEG 图像并将其绘制到窗口上。
  3. 图像大于屏幕区域时如何滚动图像(通过使用触笔)。

图像查看器示例快速预览

wmimgvwr 是一个使用 Visual Studio 2005 编码的 C++/MFC 应用程序。您可以为 PPC 2003 或 Windows Mobile 5 构建最终的可执行文件。vmimgvwr 有两种打开图像的方式

  1. 在不带参数启动的情况下,将显示一个“打开文件”对话框(CFileDialog)(**图 1**)。CFileDialog 的主要问题是它只能访问“\我的文档”文件夹中的文件和文件夹。
  2. 通过传递完整的图像路径来启动它,例如,应用程序可以通过调用CreateProcess API 函数来启动 wmimgvwr
PROCESS_INFORMATION procInfo;

CreateProcess( L"\\Apps\\wmimgvwr.exe",
               L"\\Images\\fig1.bmp",
               NULL,
               NULL,
               FALSE,
               NULL,
               NULL,
               NULL,
               NULL,
               &procInfo );
Screenshot - wmimgvwr_02.jpg

图 1

窗口的左上角有一个关闭按钮。实际上,它不是一个按钮,而是一个图片控件(**图 2**)。当您滚动图像时,该按钮不可见。因此,您可以查看所有图像细节(**图 3**)。

Screenshot - wmimgvwr_03.jpg

图 2

Screenshot - wmimgvwr_04.jpg

图 3

理解源代码

现在是时候解释源代码的主要点了。

1. 如何将窗口切换到全屏模式

Pocket PC 的屏幕分辨率较低(320x240 或 240x240)。因此,最好利用所有分辨率来显示图像,对吗?wmimgvwr 是一个对话框应用程序。它是一个没有标题栏或系统菜单的对话框。但是,这还不够。我们需要一些代码来将对话框切换到全屏模式。请查看 wmimgvwrDlg.cpp(**第 91 行**)

// *** FULL SCREEN - BEGIN
   SHINITDLGINFO shidi;
   (void) ::ZeroMemory(&shidi, sizeof(shidi));
   shidi.dwMask  = SHIDIM_FLAGS;
   shidi.dwFlags = SHIDIF_FULLSCREENNOMENUBAR;
   shidi.hDlg    = this->m_hWnd;

   ::SHInitDialog(&shidi);

   this->uf_full_screen(); 
   // *** FULL SCREEN - END

SHInitDialog 用于使用 SHIDIF_FULLSCREENNOMENUBAR 将对话框设置为全屏,它会移除对话框中的命令栏。令人惊讶的是,结果并不是一个全屏窗口,但它仍然是必需的。请记住,函数 uf_full_screen() 包含了其余的必要代码(wmimgvwrDlg.h,**第 60 行**)

void uf_full_screen(BOOL _bMove = TRUE)
   {
      HWND hBar = ::SHFindMenuBar(this->m_hWnd);
      ::CommandBar_Show( hBar, FALSE );

      this->SetForegroundWindow();
      ::SHFullScreen( this->m_hWnd, 
          SHFS_HIDETASKBAR | SHFS_HIDESIPBUTTON | SHFS_HIDESTARTICON );

      RECT cliRect;
      this->GetClientRect(&cliRect);

      if ( _bMove )
      {
         cliRect.top -= vg_wintask_h;
         cliRect.bottom += vg_wintask_h;
         this->MoveWindow(&cliRect);
      }
   }

函数的前两行包含隐藏命令栏的代码(SHFindMenuBarCommandBar_Show)。接下来,SHFullScreen 授予对话框窗口覆盖任务栏和 SIP 按钮的权限。这是我找到的描述 SHFullScreen 实际功能的最佳方式,因为调用它并不会产生全屏窗口。此外,您必须在调用它之前调用 SetForegroundWindow

最后,您必须调整窗口大小以覆盖所有屏幕。我的意思是窗口也必须覆盖任务栏区域。那么,任务栏的高度是多少?通常是 26 像素,但我们永远无法确定。请查看变量 vg_wintask_hwmimgvwrDlg.h,**第 73 行**)。它的值是任务栏的高度。 wmimgvwr.cpp,**第 52 行** 显示了它如何获取该值。

2. 如何加载 JPEG 图像文件并将其绘制到窗口上

位图绘制在窗口的客户区域。因此,您只需要加载位图文件,获取句柄,然后使用适当的函数进行绘制。MFC 为我们提供了 CBitmapCDC 类。两者都足以加载和显示位图文件,但 JPEG 文件呢?

您可能会认为这是一个问题,因为没有 CJPEG 类来加载 JPEG 文件并将其转换为位图。事实上,即使是像 LoadImage 这样的基本函数也只接受位图、图标或光标文件进行加载。别担心;您不必在互联网上搜索 Windows CE 的 JPEG 库。请查看定义在 wmimgvwrDlg.cpp(**第 183 行**)中的 uf_load_bitmap 成员函数。有一个很棒的函数叫做 SHLoadImageFile,它允许应用程序加载各种类型的图像并将它们全部转换为位图!然后,应用程序可以将 CBitmap 类附加到 SHLoadImageFile 返回的位图句柄上,并轻松处理它。请注意,它可以加载 GIF 和 PNG 文件。

3. 图像大于屏幕区域时如何滚动图像(通过使用触笔)

将位图绘制到窗口的客户区域是一个简单的过程,只需调用 BitBlt 函数并传递正确的参数。如何控制这些参数值可能是一个问题。定义在 wmimgvwrDlg.cpp(**第 125 行**)中的成员函数 OnPaint 在每次窗口需要重绘时都会被调用。以下代码在调用 OnPaint 时始终执行

dc.BitBlt( this->m_img_pos.dc_x, 
            this->m_img_pos.dc_y, 
            this->m_img_pos.dc_crop_cx, 
            this->m_img_pos.dc_crop_cy, 
            &this->m_dcMem, 
            this->m_img_pos.bmp_x, 
            this->m_img_pos.bmp_y, 
            SRCCOPY );

成员变量 m_img_pos 是在 globals.h 中定义的结构。一些字段在 uf_load_bitmap 中初始化,另一些在 uf_calc_bmp_pos 成员函数(wmimgvwrDlg.cpp,**第 148 行**)中初始化。uf_calc_bmp_pos 执行以下操作:如果图像小于窗口的客户区域,则图像在窗口中居中。否则,图像的中心部分会绘制在窗口的客户区域。

图像滚动在 PreTranslateMessage 成员函数(wmimgvwrDlg.cpp,**第 227 行**)中控制。请注意关闭按钮的可见状态是如何控制的(**第 239 行**和**第 301 行**)。WM_MOUSEMOVE 消息被处理以处理滚动,只有当图像不适合窗口时才会发生滚动。m_img_pos 结构中的两个布尔字段控制图像滚动:bmp_scroll_xbmp_scroll_y

bmp_xbmp_y 字段是根据触笔动作的值进行更改的字段。最后,如果确实发生了滚动,则会调用 Invalidate 来强制重绘窗口的客户区域(**第 295 行**)。

尽情享受吧。希望这有帮助。

历史

2007 年 11 月 23 日 -- 初始版本

© . All rights reserved.