DIBLOOK 示例:阐释如何使用 DIB 和调色板

更新:2007 年 11 月

DIBLOOK 示例阐释如何使用设备无关位图 (DIB) 和密切相关的调色板。

DIBLOOK 还阐释一个具有外部定义的文件格式(在本例中为 DIB 文件格式)的文档。这与内部定义的文件格式相反。当框架自动调用文档的 Serialize 函数以存储磁盘上的文档内容时,另外暗含了此格式。DIBLOOK 进一步阐释如何使用剪贴板、CFile 和滚动视图。

安全说明:

提供该示例代码是为了阐释一个概念,并不代表着最安全的编码实践,因此不应在应用程序或网站中使用该示例代码。对于超出本示例代码的预期用途以外的使用所造成的偶然或继发性损失,Microsoft 不承担任何责任。

获取示例和安装示例的说明:

  • 在 Visual Studio 的“帮助”菜单上,单击“示例”。

    有关更多信息,请参见定位示例文件

  • 示例的最新版本和完整列表可以从 Visual Studio 2008 Samples page(Visual Studio 2008 示例页面)联机获取。

  • 还可以在计算机的硬盘上查找示例。默认情况下,示例和自述文件将复制到 \Program Files\Visual Studio 9.0\Samples\ 下的文件夹中。对于 Visual Studio 速成版,所有示例都位于联机位置。

生成并运行示例

生成并运行 DIBLOOK 示例

  1. 打开解决方案 DibLook.sln。

  2. 在“生成”菜单中单击“生成”。

  3. 在“调试”菜单中,单击“开始执行(不调试)”。

DIBLOOK 是一个允许同时查看多个位图的多文档界面 (MDI) 应用程序。使用“File Open”打开现有的设备无关位图 (.dib) 文件或设备相关位图 (.bmp) 文件。或者可以创建新的位图文档,方法是使用剪贴板从其他应用程序(如“画图”)复制一个位图,如下所示:

  • 将位图从其他应用程序复制到剪贴板。

  • 使用 DIBLOOK“File”菜单上的“New”命令创建一个新位图文档。

  • 使用“Edit”菜单上的“Paste”命令将位图从剪贴板复制到新文档中。

尽管无法在 DIBLOOK 中编辑图像,但可以通过使用“文件”菜单上的“另存为”命令将位图保存到另一个文件。该位图以设备无关位图格式保存,即使其原始格式为设备相关。

外部定义的文档格式

DIBLOOK 以标准 Windows 设备无关位图格式读取和存储位图。而在内存中,位图则由 Windows 使用不透明 HDIB 句柄管理。位图的内部格式对应用程序是可见的。因此,DIBLOOK 的文档本身并不存储位图位或颜色表。相反,CDibDoc 保存 DIB 的句柄 (HDIB m_hDIB)。DIBLOOK 是在外部定义文档格式的应用程序(通常是一些标准的文件格式标准,如 DIB),这与按照在 CDocument::Serialize 重写中序列化文档项的顺序隐式定义文档格式的应用程序相反。

DIBLOOK 不重写 CDocument::Serialize。相反,它重写 CDocument::OnOpenDocumentOnSaveDocument。这两个重写都使用框架传入的 pszPathName 打开 CFile 对象并读取或保存 DIB。Myfile.cpp 中提供了用于读取和保存 DIB 文件的实际代码;这些代码可由任何需要读取并保存 DIB 文件的应用程序重用。

使用 DIB 和调色板

DIBLOOK 阐释如何在窗口中显示 DIB 和如何为该窗口显示 DIB 准备调色板。

DIBLOOK 从文件中读取 DIB 后,它根据 DIB 的颜色表准备 CPalette 对象,并在 CDibDoc 对象中将调色板存储为 m_palhDIB。当 DIBLOOK 在其 CDibView::OnDraw 中显示 DIB 时,它调用在 DIBLOOK 的 Dibapi.cpp 文件中实现的 Windows 例程 ::PaintDIBPaintDIB 然后调用 Windows 函数 ::SetDIBitsToDevice::StretchDIBits 并将 DIB 的颜色表用作调色板。Dibapi.cpp 中的 DIB 显示例程可由任何显示 DIB 的应用程序重用。

DIBLOOK 为当前活动的窗口选择一个最佳的调色板。DIBLOOK 选择一个与当前活动的 MDI 子窗口中显示的 DIB 颜色表相匹配的调色板。当应用程序要接收输入焦点(由其他应用程序转移出)时,其顶级窗口接收 WM_QUERYNEWPALETTE 消息。DIBLOOK 的 CMainFrame 窗口通过向每个子代窗口发送应用程序定义的消息 WM_DOREALIZE 来处理此消息。子代窗口列表包括可能的多个打开文档的所有视图。然后,每个视图在其显示上下文中选择作为前景或背景调色板,具体取决于该视图是否活动。

如果其他应用程序更改系统调色板,则 DIBLOOK 接收 WM_PALETTECHANGED 消息。在这种情况下,CMainFrame 窗口再次向每个视图发送应用程序定义的消息 WM_DOREALIZE。但是,每个视图在显示上下文中选择其调色板作为背景调色板,并为其他应用程序产生前景调色板。

当焦点在应用程序内从一个视图转移到另一个视图时,DIBLOOK 为当前活动的视图选择和实现调色板(请参见 CDibView::OnActivateView)。实现新调色板后,Windows 向所有应用程序顶级窗口(包括 DIBLOOK 的顶级窗口)发送 WM_PALETTECHANGED 消息。DIBLOOK 通过将与其他视图中的其他 DIB 关联的颜色表实现为背景调色板来处理此消息。

关键字

此示例说明以下关键字:

AfxGetApp;CCmdTarget::BeginWaitCursor;CCmdTarget::EndWaitCursor;CCmdUI::Enable;CDC::RealizePalette;CDC::SelectPalette;CDialog::DoModal;CDocument::DeleteContents;CDocument::OnNewDocument;CDocument::OnOpenDocument;CDocument::OnSaveDocument;CDocument::ReportSaveLoadException;CDocument::SetModifiedFlag;CDocument::SetPathName;CDocument::UpdateAllViews;CFile::Abort;CFile::Close;CFile::GetLength;CFile::Open;CFile::Read;CFile::ReadHuge;CFile::Write;CFile::WriteHuge;CFrameWnd::GetActiveView;CFrameWnd::LoadFrame;CMDIFrameWnd::MDIGetActive;CObject::AssertValid;CObject::Dump;CPalette::CreatePalette;CScrollView::SetScrollSizes;CStatusBar::Create;CStatusBar::SetIndicators;CString::LoadString;CToolBar::Create;CToolBar::LoadBitmap;CToolBar::SetButtons;CView::DoPreparePrinting;CView::GetDocument;CView::OnActivateView;CView::OnDraw;CView::OnInitialUpdate;CView::OnPreparePrinting;CWinApp::AddDocTemplate;CWinApp::EnableShellOpen;CWinApp::InitInstance;CWinApp::LoadStdProfileSettings;CWinApp::RegisterShellFileTypes;CWnd::DoDataExchange;CWnd::OnCreate;CWnd::OnPaletteChanged;CWnd::OnQueryNewPalette;CWnd::OpenClipboard;CWnd::SendMessage;CWnd::SendMessageToDescendants;CWnd::ShowWindow;CWnd::UpdateWindow;CloseClipboard;DragAcceptFiles;EmptyClipboard;GetClipboardData;GetDeviceCaps;GlobalAlloc;GlobalFree;GlobalLock;GlobalSize;GlobalUnlock;IsClipboardFormatAvailable;MessageBox;SelectPalette;SetClipboardData;SetDIBitsToDevice;SetStretchBltMode;StretchDIBits;memcpy

说明:

某些示例(如此示例)尚未经过修改以反映 Visual C++ 向导、库和编译器中所做的更改,但仍演示了如何完成所需的任务。

请参见

其他资源

MFC 示例