常见故障的排除

常见网络故障故障全面排除方案

----------------------------------------------------------------------------


网络故障

故障一、Windows 98拨号上网的速度太慢

故障现象:

  在Windows 98中采用“拨号网络”拨号上网时,系统用于验证用户名及密码的时间明显
增加,须要一分多钟(在Windows 95中只要几秒针)。

故障分析:

  这主要是Windows 98在拨号上网的同时采用了NetBEUI、IPX/SPX及TCP/IP三种协议(而
事实上连接Internet只需要TCP/IP协议),以及使用了不恰当的“试图使用登录到Windows 9
8时使用的用户名登录到网络上”的登录方式,从而影响Windows 98的拨号登录速度。我们只
须删除两种无用的网络协议并禁止Windows 98使用不恰当的登录方式即可。

解决方法:

  打开“拨号网络”窗口,然后采用鼠标右击相应的拨号链接方式(如“我的链接”),
并从弹出的快捷菜单中执行“属性”命令,系统弹出拨号网络属性对话框(如图16),然后单
击“服务器类型”选项卡,最后从中取消“登录网络”、“NetBEUI协议”和“IPX/SPX协议”
三个选项即可。

故障二、 Outlook Express的通讯录不见了

故障现象:

  重装Outlook Express之后,原有的通讯录全部不知去向。

故障分析:

  Outlook Express的通讯录一般都保存在*.WAB文件中,我们只须找到这些文件即可解决
问题。

解决方法:

  单击“开始/查找/文件和文件夹”命令,打开“查找文件”对话框,在“名称”栏中输
入“*.WAB"、在“搜索”栏中选择搜索“我的电脑”(即所有的磁盘分区),然后复选“包含
子文件夹”选项,最后单击“开始查找”按钮。将查找到的文件拷贝到C:\WINDOWS\Applicat
ion Data\Microsoft\Address Book子目录即可。

故障三、别人知道我在某个站点停留了多少时间

故障现象:

  不论是使用IE还是使用NC,当我浏览某些站点时,它们总能知道我采用的操作系统和浏
览器、访问该站点的次数及每次停留的时间。有什么办法可以防止这种泄密的发生?

故障分析:

  这些站点是通过用户计算机中的Cookies文件来记录和查找这些信息的,我们只要将该文
件中的内容删除并将文件属性修改为只读即可解决。

解决方法:

  用户若使用的是Navigator,应打开Netscape目录,然后将该目录中的Cookies.txt文件
内容删除并将文件属性改为只读;用户若使用的是IE,应打开Windows 目录中的Cookies文件
夹,将该文件夹的属性修改为只读。

故障四、IE分级审查功能的监护人密码丢失

故障现象:

  IE具有分级审查功能,它可防止未经授权的用户访问那些不太合适的网站。在使用IE的
分级审查功能前必须设置控制密码,但是现在我忘记了分级审查密码,不能再对分级审查功能
的权限进行调整了。

故障分析:

  IE的分级审查功能密码保存在系统的注册表数据库中,我们只须对其进行适当修改即可
解决问题。

解决方法:

  启动注册表编辑器Regedit.exe,依次展开HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft
\Windows\CurrentVersion\Policies\Ratings主键,在该主键下有一个名为“KEY”的键
值就是IE 4.0的“分级审查”口令(数据已经加密),用户只须删除该键值即可取消IE 4.0的
“分级审查”口令。

----------------------------------------------------------------------------

标 题: Re: LAN下的语音实时传输
发信站: BBS 水木清华站 (Sun May 3 09:59:05 1998) WWW-POST
 
 
【 在 netron (puppy) 的大作中提到: 】
: 用VC实现,听说要用到DSP编程,不知能否用VC来做
:
: 请在这方面有经验的人多多赐教
: ※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 202.112.105.68]
发送端:
 用waveInOpen打开录音设备,用waveInPrepareHeader,waveInAddBuffer
添加缓冲,在回调函数中调用waveInUnprepareHeader后,发送以录完的数据
接收端:
 用waveOutOpen打开设备,用waveOutPrepareHeader,waveOuWrite播放声音。
※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 162.105.160.161]

发信人: zg (zg), 信区: VisualC
标 题: Re: 如何用MCI播放MIDI?
发信站: BBS 水木清华站 (Sun May 3 17:16:01 1998)
 
【 在 radish (蓝天白云) 的大作中提到: 】
: 怎么用mciSendString()? 麻烦您给我个例子。这里先谢了。
 
char cmds[100];
wsprintf(cmds,"open sequencer!your.mid alias yoursound");
mciSendString(cmds,cmds,100,this->m_hWnd);
wsprintf(cmds,"play yoursound notify");
mciSendString(cmds,cmds,100,this->m_hWnd);
在程序结束时别忘了
wsprintf(cmds,"close yoursound");
mciSendString(cmds,cmds,100,this->m_hWnd);
 
--
※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: ns.cstnet-hf.ne]
 

 发信人: station (asdf), 信区: VisualC
标 题: Re: 如何知道声音Buffer 已经装满
发信站: BBS 水木清华站 (Tue May 19 19:55:46 1998)
 
在使用waveInOpen是可指定当buffer填满时向窗口或线程发送MM_WIM_DATA消息,
在MM_WIM_DATA的参数中含有关于buffer的信息(wParam为hWaveIn,
lParam为waveHdr结构的地址),在waveHdr结构的lpData中为buffer的指针,
还有一个参数是buffer中数据的长度(sorry具体名字记不清了)。
你在仔细看以下help吧.
 
【 在 xact (小高) 的大作中提到: 】
: 各位,我在用声卡录制声音时,首先用WaveInOpen打开了声卡,然后用WaveInPrepareHea
ader,和
: WaveInAddBuffer准备录音,最后用WaveInStart启动录音过程,但我不知道如何让系统通
通知我声?
: Buffer 已经装满,在WaveInOpen函数中有一个Callback 函数,但不知如何使用,请各位
位高手指教?
: ※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 202.112.105.92]
 
 
--
※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 162.105.160.161]
 
 发信人: telnet (小飞象), 信区: VisualC
标 题: Re: 怎么能从AVI文件中将每幅图以BMP文件取出
发信站: BBS 水木清华站 (Thu Mar 25 19:05:44 1999)
 
去看看VC的例子是叫AVIVIEW的,用AVI***族函数可以
【 在 steve1 (李二麻子) 的大作中提到: 】
:
: 在下需要将AVI文件中的每幅画面取出,并以bmp的格式保存,由于画面太多,不能用其他

: 软件手工完成,因此需要编程,请那位大虾指教。
 
 
--
※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 202.112.101.44]
 
 发信人: Norwelect (沉默的马铃薯-戒网一月中), 信区: VisualC
标 题: [转贴] 用VC++5.0播放AVI文件的两种方法
发信站: BBS 水木清华站 (Thu Apr 22 08:35:42 1999) WWW-POST
 
copy from 【创思电子刊物---电脑资讯】
 
    用VC++5.0播放AVI文件的两种方法
         文/刘海文&朱辉
   用Visual C++开发的面向对象的多媒体应用软件可编译成
真正的EXE可执行文件,无需附加动态库和控件,如VBX和OCX
等。有两种方法可以实现这个功能,一种方法是使用底层AVI
文件函数,从AVI视频文件中读取视频流;另一种是使用现有的
Video forin dows SDK的窗口类MCIWnd(媒体控制界面窗)。
本文将介绍基于VC++5.0环境下,开发播放AVI文件的两种方
法,这两种方法略作改动, 还可为应用程序播放其它的媒体文
件(如声音文件等)。
 
一. VC++5.0可通过调用VFW.H和VFW32.LIB和MCIWnd API
函数来创建MCIWnd窗口实现AVI多媒体文件的调用和播放。
 
1. MCIWnd是一个控制多媒体设备(如MIDI、数字视频、VCR
以及CD音频设备等)的窗口类,要制作多媒体封面只需创建该
类的一个窗口,然后向它发送打开和控制MCI设置的消息。
MCIWnd窗口底部的播放条(Playbar )包括一个播放/暂停
(Play/Pause)按键、一个显示菜单(menu)按键和一个用于报告
播放进程的标尺。在播放窗口的任何地方单击鼠标右键都会显
示一个弹出菜单, 用于调整MCIWnd窗口的大小、MCI多媒体文
件的声音、速度的大小、MCI命令等。而且在父窗口外单击鼠
标右键可关闭和清除MCIWnd窗口,单击鼠标左键则可恢复
MCIWnd窗口。
 
2.编程步骤
  首先在VC++5.0中建立一个名为playavi项目( project)。
然后,通过调用VC++5.0的类库,从而建立OnLButtonDown()和
OnRButtonDown()函数。在相应的视文件(playaviView.cpp)
开始处加入一行#include "vfw.h",在显示类的构造函数中加
入一行" m_mmWnd=NULL",在相应的视文件的头文件中加入:
 
 
 
   private:
 
    HWND m_mmWnd;
 
    BOLL m_pause;
 
 
 
在源文件playavi.cpp相应的函数中输入如下代码:
 
 
// CPlayaviView message handlers
 
 
void CPlayaviView::OnLButtonDown(UINT nFlags, CPoint point)
 
{
 
     // TODO: Add your message handler code here and/or call default
 
 
     //加入我的代码
 
     CString filename("\filename.avi");//键入文件路径及文件名
 
    if(m_mmWnd==NULL)
 
     m_mmWnd=MCIWndCreate(this->GetSafeHwnd(),AfxGetInstanceHandle(),
 
     WS_CHILD|WS_CAPTION|WS_VISIBLE|MCIWNDF_SHOWPOS|MCIWNDF_SHOWNAME,
 
     //以上为开关选项
 
     filename);// filename为要播放的avi文件名
 
    else
 
    {
 
 
     //设置播放句柄
 
     if(m_pause)
 
     {
 
    MCIWndPlay(m_mmWnd);
 
    m_pause=FALSE;
 
     }
 
 
     //设置中断句柄
 
     else
 
     {
 
    MCIWndPause(m_mmWnd);
 
    m_pause=TRUE;
 
     }
 
      }
 
     //结束我的代码
 
     CView::OnLButtonDown(nFlags, point);
 
}
 
 
void CPlayaviView::OnRButtonDown(UINT nFlags, CPoint point)
 
{
 
     // TODO: Add your message handler code here and/or call default
 
 
     //加入我的代码
 
     if (m_mmWnd!=NULL)
 
    {
 
   MCIWndDestroy(m_mmWnd);
 
   m_mmWnd=NULL;
 
    }
 
     //结束我的代码
 
     CView::OnRButtonDown(nFlags, point);
 
}
 
 
   最后,在Project Setting对话框的Link表中将VFW32·LIB加
入Object/Library Modules对话框,最后编译该项目,即可播放了。
 
 
二. 在VC++5.0创建MCIWnd一个窗口,然后向它发送打开和控制MCI
设置的消息,也可实现播放AVI文件。
 
   1.编辑Stdafx.h
 
     // stdafx.h : include file for standard system include files,
 
// or project specific include files that are used frequently, but
 
//   are changed infrequently
 
 
#if !defined(AFX_STDAFX_H__A851EC08_00FE_11D2_B7EF_00C0DF81AC80__INCLUDED_)
 
#define AFX_STDAFX_H__A851EC08_00FE_11D2_B7EF_00C0DF81AC80__INCLUDED_
 
 
#if _MSC_VER >= 1000
 
#pragma once
 
#endif // _MSC_VER >= 1000
 
 
#define VC_EXTRALEAN      // Exclude rarely-used stuff from Windows
headers
 
 
#include      // MFC core and standard components
 
#include      // MFC extensions
 
#include
 
#pragma comment(lib,"vfw32.lib")
 
#include     // MFC OLE automation classes
 
#ifndef _AFX_NO_AFXCMN_SUPPORT
 
#include
 
// MFC support for Windows Common Controls
 
#endif // _AFX_NO_AFXCMN_SUPPORT
 
 
 
//{{AFX_INSERT_LOCATION}}
 
// Microsoft Developer Studio will insert additional declarations
immediately
//before the previous line.
 
#endif
// !defined(AFX_STDAFX_H__A851EC08_00FE_11D2_B7EF_00C0DF81AC80__INCLUDED_)
 
 
   2.编辑CExampleApp::InitInstance()
 
   注册MCIWnd窗口类,打开MCIWnd窗口,并播放AVI文件,最后关闭
MCIWnd窗口,然后开始应用程序的常规初始化。
 
   BOOL CAApp::InitInstance()
 
{
 
     // CG: The following block was added by the Splash Screen
component.
 
     {
 
         CCommandLineInfo cmdInfo;
 
         ParseCommandLine(cmdInfo);
 
     }
 
     // CG: The following block was added by the Splash Screen
component.
 
 
 
     {
 
         CCommandLineInfo cmdInfo;
 
         ParseCommandLine(cmdInfo);
 
     }
 
     AfxEnableControlContainer();
 
 
     // Standard initialization
 
     // If you are not using these features and wish to reduce the size
 
     // of your final executable, you should remove from the following
 
     // the specific initialization routines you do not need.
 
 
     //加入我的代码
 
     if(!MCIWndRegisterClass())//注册MCIWnd窗口类
 
         return FALSE;
 
     HWND m_hAVI;//定义一个播放AVI文件的窗口句柄
 
     m_hAVI=MCIWndCreate(NULL,AfxGetInstanceHandle(),
 
         WS_VISIBLE|WS_POPUP,NULL);//创建MCIWnd窗口
 
 
     if(m_hAVI==NULL)
 
         return FALSE;
 
     CString filename="\filename.avi");//键入文件路径及文件名
 
     if(filename.GetLength()>0)
 
     {
 
         MCIWndOpen(m_hAVI,(LPCSTR)filename,0);//打开设备文件
 
 
 
         if(MCIWndUseTime(m_hAVI)!=0)
 
         //设置MCI时间格式
 
             return FALSE;
 
         long PlayTime=MCIWndGetLength(m_hAVI);
 
         //获得AVI文件的播放时间长度
 
         MCIWndPlay(m_hAVI);//播放AVI影视文件
 
         ::Sleep(PlayTime);//进程休眠
 
         MCIWndDestroy(m_hAVI);//关闭MCI窗口
 
     }
 
     //结束我的代码
 
     //开始常规初始化
 
#ifdef _AFXDLL
 
     Enable3dControls();
 
// Call this when using MFC in a shared DLL
 
#else
 
     Enable3dControlsStatic();
 
// Call this when linking to MFC statically
 
#endif
 
     // Change the registry key under which our settings are stored.
 
     // You should modify this string to be something appropriate
 
     // such as the name of your company or organization.
 
     SetRegistryKey(_T("Local AppWizard-Generated Applications"));
 
 
     LoadStdProfileSettings();
 
  // Load standard INI file options (including MRU)
 
 
     // Register the application`s document templates. Document
templates
 
     // serve as the connection between documents, frame windows and
//views.
 
 
     CSingleDocTemplate* pDocTemplate;
 
     pDocTemplate = new CSingleDocTemplate(
 
         IDR_MAINFRAME,
 
         RUNTIME_CLASS(CADoc),
 
         RUNTIME_CLASS(CMainFrame),    // main SDI frame window
 
         RUNTIME_CLASS(CAView));
 
     AddDocTemplate(pDocTemplate);
 
 
 
     // Parse command line for standard shell commands, DDE, file open
 
     //CCommandLineInfo cmdInfo;
 
     ParseCommandLine(cmdInfo);
 
 
     // Dispatch commands specified on the command line
 
     if (!ProcessShellCommand(cmdInfo))
 
         return FALSE;
 
 
     // The one and only window has been initialized, so show and update
//it.
 
     m_pMainWnd->ShowWindow(SW_SHOW);
 
     m_pMainWnd->UpdateWindow();
 
 
 
     return TRUE;
 
}
 

 
三. 结束语
   以上两种方法,笔者在VC++5.0中已调试通过。只要略作改动, 它
们还可为应用程序播放其它的多媒体文件(如声音文件等)。亲爱的读
者,您不妨一试!
 
 
 
--
没有忧愁,
也无需快乐,
我是一个自在的土豆.
 

 
 
发信人: woody ( 沱沱 ), 信区: VisualC
标 题: Re: 声卡录音时有无延时?
发信站: BBS 水木清华站 (Thu May 6 13:13:08 1999)
 
according to the documents of MS, the delay is 100ms to 300ms
some kind of directsound driver can be much less, it depends on
the hardware provider
 
【 在 newgod (宝宝) 的大作中提到: 】
: 声卡录音时,是否也是用声卡上的缓冲区一段段地录音,
: 这样的话,她本生会有多大延时???
 
 
--
我爱你在这陌生的城市里,不管明天如何继续.
 
※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 166.111.66.223]
 
 发信人: telnet (小飞象), 信区: VisualC
标 题: 不要怀疑了,JDK是对的
发信站: BBS 水木清华站 (Sun Oct 3 14:07:23 1999)
 
中午吃饭时试了一下,成功了。
我看了MSDN也以为只对BMP有用,结果是对JPG GIF都可以。
向不轻信MS的JDK致敬!
//admire JDK
以下是实验代码,大家可以在95下试试,我在98+IE5上成功。
是一个CView的例子,别忘了AfxOleInit
另,时间短,写得很乱,,大家自行改进吧!
 
void CPICView::OnDraw(CDC* pDC)
{
CPICDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
 
IPicture *pPic;
IStream *pStm;
 
CFileStatus fstatus;
CFile file;
LONG cb;
 
if (file.Open("c:/test.jpg",CFile::modeRead)&&file.GetStatus("c:/test.jpg",
fstatus)&&
 ((cb = fstatus.m_size) != -1))
{
 HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, cb);
 LPVOID pvData = NULL;
 if (hGlobal != NULL)
 {
  if ((pvData = GlobalLock(hGlobal)) != NULL)
  {
  file.ReadHuge(pvData, cb);
  GlobalUnlock(hGlobal);
  CreateStreamOnHGlobal(hGlobal, TRUE, &pStm);
 
  if(SUCCEEDED(OleLoadPicture(pStm,fstatus.m_size,TRUE,IID_IPicture,(LPVOID*
)&pPic)))
  {
   OLE_XSIZE_HIMETRIC hmWidth;
   OLE_YSIZE_HIMETRIC hmHeight;
 
   pPic->get_Width(&hmWidth);
   pPic->get_Height(&hmHeight);
 
   double fX,fY;
   fX = (double)pDC->GetDeviceCaps(HORZRES)*(double)hmWidth/((double)pDC-&g
t;Ge
tDeviceCaps(HORZSIZE)*100.0);
   fY = (double)pDC->GetDeviceCaps(VERTRES)*(double)hmHeight/((double)pDC-&
gt;G
etDeviceCaps(VERTSIZE)*100.0);
   if(FAILED(pPic->Render(*pDC,0,0,(DWORD)fX,(DWORD)fY,0,hmHeight,hmWidth,-
h
mHeight,NULL)))
   AfxMessageBox("Failed To Render The picture!");
   pPic->Release();
  }
  else
   AfxMessageBox("Error Loading Picture From Stream!");
  }
 }
}
else
 AfxMessageBox("Can't Open Image File!");
}
 

--
※ 修改:·telnet 於 Oct 3 14:22:17 修改本文·[FROM: 202.113.28.245]

 
 
 
 发信人: vicluck (阿海), 信区: VisualC
标 题: Re: 播放*.AVI文件怎样知其播放完毕?
发信站: BBS 水木清华站 (Sat Dec 11 12:06:25 1999)
 
结束时CAnimateCtrl会向窗口发送WM_COMMAND消息,其中HIWORD(wParam)是ACN_STOP.
【 在 Jorling (Kiddy) 的大作中提到: 】
:  小弟在程序启动时打算在播放一个*.AVI文件,现在是在对话框的Animation控件中
: 播放,但是怎样才能知道文件已经播放完,然后Destroy这个对话框呢?
:  不胜感激。
 
 
--
※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 202.120.189.34]
 
 
 
 
 发信人: Fanpang (饺子), 信区: VisualC
标 题: Re: 请教如何将CBitmap的内容存为BMP文件
发信站: BBS 水木清华站 (Thu Mar 9 12:28:12 2000)
 
用技术内幕中的CDib类,该类中有一个Write方法,可以实现bmp文件的存储。
具体例子如下:
 
CDib dib(size,16); //定义CDib对象,其中size为CSize对象,表示图像的大小,16表
示图像颜色(?16位增强色);
CBitmap Bmp; //定义CBitmap对象
HBITMAP hBitmap=dib.CreateSection(&dc); //通过CDib对象创建相应的Bitmap图像句柄;

CBitmap* pBmp=Bmp.FromHandle(hBitmap); //由hiBitmap创建指向CBitmap对象的指针;
CDC dcMemory; //定义显示设备环境类对象;
dcMemory.CreateCompatibleDC(&dc); //创建一个与窗口客户区域相兼容的显示内存块;
CBitmap* pBmpOld=dcMemory.SelectObject(pBmp); //把CBitmap对象选入内存显示块?
//在此加入你的绘图语句
dcMemory.绘图方法....
...?
//?..
CFile bmpFile; //创建CFile对象bmpFile;
bmpFile.Open(strBMPFileName, CFile::modeCreate | CFile::modeWrite); //创建文件

dib.Write(&bmpFile); //存储BMP文件;

bmpFile.Close(); //关闭文件;
dcMemory.SelectObject(&pBmpOld); //释放CBitmap对象所占的内存空间;
 
【 在 shens (eh) 的大作中提到: 】
: 我已经在内存中建立了内存兼容的CBitmap,向里面进行绘图操作,使用BitBlt将
: 其显示到屏幕窗口中,现在不知道如何将所绘的图存到bmp文件中,不知道cBitmap
: 类能否直接存bmp,请赐教,谢谢
 
 发信人: Fanpang (饺子), 信区: VisualC
标 题: Re: 请教如何将CBitmap的内容存为BMP文件
发信站: BBS 水木清华站 (Thu Mar 9 13:30:16 2000)
 
在VISUAL C++ 技术内幕(第四版)的光盘上。
把光盘里的vcpp32\ex10h目录下的Cdib.h和cdib.cpp copy 到工程目录下
并且把Cdib文件加到工程里。(可参考该书第199页)
如果没有这书,下面是CDdib.h和cdib.cpp 的源代码:
// cdib.h declaration for Inside Visual C++ CDib class
#ifndef _INSIDE_VISUAL_CPP_CDIB
#define _INSIDE_VISUAL_CPP_CDIB
class CDib : public CObject
{
enum Alloc {noAlloc, crtAlloc, heapAlloc};
DECLARE_SERIAL(CDib)
public:
LPVOID m_lpvColorTable;
HBITMAP m_hBitmap;
LPBYTE m_lpImage; // starting address of DIB bits
LPBITMAPINFOHEADER m_lpBMIH; // buffer containing the BITMAPINFOHEADER
private:
HGLOBAL m_hGlobal; // For external windows we need to free;
          // could be allocated by this class or allocated extern
ally
Alloc m_nBmihAlloc;
Alloc m_nImageAlloc;
DWORD m_dwSizeImage; // of bits -- not BITMAPINFOHEADER or BITMAPFILEHEADER
 
int m_nColorTableEntries;
HANDLE m_hFile;
HANDLE m_hMap;
LPVOID m_lpvFile;
HPALETTE m_hPalette;
public:
CDib();
CDib(CSize size, int nBitCount); // builds BITMAPINFOHEADER
~CDib();
int GetSizeImage() {return m_dwSizeImage;}
int GetSizeHeader()
 {return sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries;
}
CSize GetDimensions();
BOOL AttachMapFile(const char* strPathname, BOOL bShare = FALSE);
BOOL CopyToMapFile(const char* strPathname);
BOOL AttachMemory(LPVOID lpvMem, BOOL bMustDelete = FALSE, HGLOBAL hGlobal
= NULL);
BOOL Draw(CDC* pDC, CPoint origin, CSize size); // until we implemnt Creat
eDibSection
HBITMAP CreateSection(CDC* pDC = NULL);
UINT UsePalette(CDC* pDC, BOOL bBackground = FALSE);
BOOL MakePalette();
BOOL SetSystemPalette(CDC* pDC);
BOOL Compress(CDC* pDC, BOOL bCompress = TRUE); // FALSE means decompress
HBITMAP CreateBitmap(CDC* pDC);
BOOL Read(CFile* pFile);
BOOL ReadSection(CFile* pFile, CDC* pDC = NULL);
BOOL Write(CFile* pFile);
void Serialize(CArchive& ar);
void Empty();
private:
void DetachMapFile();
void ComputePaletteSize(int nBitCount);
void ComputeMetrics();
};
#endif // _INSIDE_VISUAL_CPP_CDIB
//End of CDib.h
 
// begin CDIB.CPP
// cdib.cpp
// new version for WIN32
#include "stdafx.h"
#include "cdib.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_SERIAL(CDib, CObject, 0);
CDib::CDib()
{
m_hFile = NULL;
m_hBitmap = NULL;
m_hPalette = NULL;
m_nBmihAlloc = m_nImageAlloc = noAlloc;
Empty();
}
CDib::CDib(CSize size, int nBitCount)
{
m_hFile = NULL;
m_hBitmap = NULL;
m_hPalette = NULL;
m_nBmihAlloc = m_nImageAlloc = noAlloc;
Empty();
ComputePaletteSize(nBitCount);
m_lpBMIH = (LPBITMAPINFOHEADER) new
 char[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries];
m_nBmihAlloc = crtAlloc;
m_lpBMIH->biSize = sizeof(BITMAPINFOHEADER);
m_lpBMIH->biWidth = size.cx;
m_lpBMIH->biHeight = size.cy;
m_lpBMIH->biPlanes = 1;
m_lpBMIH->biBitCount = nBitCount;
m_lpBMIH->biCompression = BI_RGB;
m_lpBMIH->biSizeImage = 0;
m_lpBMIH->biXPelsPerMeter = 0;
m_lpBMIH->biYPelsPerMeter = 0;
m_lpBMIH->biClrUsed = m_nColorTableEntries;
m_lpBMIH->biClrImportant = m_nColorTableEntries;
ComputeMetrics();
memset(m_lpvColorTable, 0, sizeof(RGBQUAD) * m_nColorTableEntries);
m_lpImage = NULL; // no data yet
}
CDib::~CDib()
{
Empty();
}
CSize CDib::GetDimensions()
{
if(m_lpBMIH == NULL) return CSize(0, 0);
return CSize((int) m_lpBMIH->biWidth, (int) m_lpBMIH->biHeight);
}
BOOL CDib::AttachMapFile(const char* strPathname, BOOL bShare) // for readin
g
{
// if we open the same file twice, Windows treats it as 2 separate files
// doesn't work with rare BMP files where # palette entries > biClrUsed
HANDLE hFile = ::CreateFile(strPathname, GENERIC_WRITE | GENERIC_READ,
 bShare ? FILE_SHARE_READ : 0,
 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
ASSERT(hFile != INVALID_HANDLE_VALUE);
DWORD dwFileSize = ::GetFileSize(hFile, NULL);
HANDLE hMap = ::CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
 
DWORD dwErr = ::GetLastError();
if(hMap == NULL) {
 AfxMessageBox("Empty bitmap file");
 return FALSE;
}
LPVOID lpvFile = ::MapViewOfFile(hMap, FILE_MAP_WRITE, 0, 0, 0); // map who
le file
ASSERT(lpvFile != NULL);
if(((LPBITMAPFILEHEADER) lpvFile)->bfType != 0x4d42) {
 AfxMessageBox("Invalid bitmap file");
 DetachMapFile();
 return FALSE;
}
AttachMemory((LPBYTE) lpvFile + sizeof(BITMAPFILEHEADER));
m_lpvFile = lpvFile;
m_hFile = hFile;
m_hMap = hMap;
return TRUE;
}
BOOL CDib::CopyToMapFile(const char* strPathname)
{
// copies DIB to a new file, releases prior pointers
// if you previously used CreateSection, the HBITMAP will be NULL (and unus
able)
BITMAPFILEHEADER bmfh;
bmfh.bfType = 0x4d42; // 'BM'
bmfh.bfSize = m_dwSizeImage + sizeof(BITMAPINFOHEADER) +
  sizeof(RGBQUAD) * m_nColorTableEntries + sizeof(BITMAPFILEHEADER);
// meaning of bfSize open to interpretation
bmfh.bfReserved1 = bmfh.bfReserved2 = 0;
bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
  sizeof(RGBQUAD) * m_nColorTableEntries;
HANDLE hFile = ::CreateFile(strPathname, GENERIC_WRITE | GENERIC_READ, 0, N
ULL,
 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
ASSERT(hFile != INVALID_HANDLE_VALUE);
int nSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
  sizeof(RGBQUAD) * m_nColorTableEntries + m_dwSizeImage;
HANDLE hMap = ::CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, nSize, NU
LL);
DWORD dwErr = ::GetLastError();
ASSERT(hMap != NULL);
LPVOID lpvFile = ::MapViewOfFile(hMap, FILE_MAP_WRITE, 0, 0, 0); // map who
le file
ASSERT(lpvFile != NULL);
LPBYTE lpbCurrent = (LPBYTE) lpvFile;
memcpy(lpbCurrent, &bmfh, sizeof(BITMAPFILEHEADER)); // file header
lpbCurrent += sizeof(BITMAPFILEHEADER);
LPBITMAPINFOHEADER lpBMIH = (LPBITMAPINFOHEADER) lpbCurrent;
memcpy(lpbCurrent, m_lpBMIH,
 sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries); // inf
o
lpbCurrent += sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEnt
ries;
memcpy(lpbCurrent, m_lpImage, m_dwSizeImage); // bit image
DWORD dwSizeImage = m_dwSizeImage;
Empty();
m_dwSizeImage = dwSizeImage;
m_nBmihAlloc = m_nImageAlloc = noAlloc;
m_lpBMIH = lpBMIH;
m_lpImage = lpbCurrent;
m_hFile = hFile;
m_hMap = hMap;
m_lpvFile = lpvFile;
ComputePaletteSize(m_lpBMIH->biBitCount);
ComputeMetrics();
MakePalette();
return TRUE;
}
BOOL CDib::AttachMemory(LPVOID lpvMem, BOOL bMustDelete, HGLOBAL hGlobal)
{
// assumes contiguous BITMAPINFOHEADER, color table, image
// color table could be zero length
Empty();
m_hGlobal = hGlobal;
if(bMustDelete == FALSE) {
 m_nBmihAlloc = noAlloc;
}
else {
 m_nBmihAlloc = ((hGlobal == NULL) ? crtAlloc : heapAlloc);
}
try {
 m_lpBMIH = (LPBITMAPINFOHEADER) lpvMem;
 ComputeMetrics();
 ComputePaletteSize(m_lpBMIH->biBitCount);
 m_lpImage = (LPBYTE) m_lpvColorTable + sizeof(RGBQUAD) * m_nColorTableEntr
ies;
 MakePalette();
}
catch(CException* pe) {
 AfxMessageBox("AttachMemory error");
 pe->Delete();
 return FALSE;
}
return TRUE;
}
UINT CDib::UsePalette(CDC* pDC, BOOL bBackground /* = FALSE */)
{
if(m_hPalette == NULL) return 0;
HDC hdc = pDC->GetSafeHdc();
::SelectPalette(hdc, m_hPalette, bBackground);
return ::RealizePalette(hdc);
}
BOOL CDib::Draw(CDC* pDC, CPoint origin, CSize size)
{
if(m_lpBMIH == NULL) return FALSE;
if(m_hPalette != NULL) {
 ::SelectPalette(pDC->GetSafeHdc(), m_hPalette, TRUE);
}
pDC->SetStretchBltMode(COLORONCOLOR);
::StretchDIBits(pDC->GetSafeHdc(), origin.x, origin.y, size.cx, size.cy,
 0, 0, m_lpBMIH->biWidth, m_lpBMIH->biHeight,
 m_lpImage, (LPBITMAPINFO) m_lpBMIH, DIB_RGB_COLORS, SRCCOPY);
return TRUE;
}
HBITMAP CDib::CreateSection(CDC* pDC /* = NULL */)
{
if(m_lpBMIH == NULL) return NULL;
if(m_lpImage != NULL) return NULL; // can only do this if image doesn't exi
st
m_hBitmap = ::CreateDIBSection(pDC->GetSafeHdc(), (LPBITMAPINFO) m_lpBMIH,
 DIB_RGB_COLORS, (LPVOID*) &m_lpImage, NULL, 0);
ASSERT(m_lpImage != NULL);
return m_hBitmap;
}
BOOL CDib::MakePalette()
{
// makes a logical palette (m_hPalette) from the DIB's color table
// this palette will be selected and realized prior to drawing the DIB
if(m_nColorTableEntries == 0) return FALSE;
if(m_hPalette != NULL) ::DeleteObject(m_hPalette);
TRACE("CDib::MakePalette -- m_nColorTableEntries = %d\n", m_nColorTableEntr
ies);
LPLOGPALETTE pLogPal = (LPLOGPALETTE) new char[2 * sizeof(WORD) +
 m_nColorTableEntries * sizeof(PALETTEENTRY)];
pLogPal->palVersion = 0x300;
pLogPal->palNumEntries = m_nColorTableEntries;
LPRGBQUAD pDibQuad = (LPRGBQUAD) m_lpvColorTable;
for(int i = 0; i < m_nColorTableEntries; i++) {
 pLogPal->palPalEntry[i].peRed = pDibQuad->rgbRed;
 pLogPal->palPalEntry[i].peGreen = pDibQuad->rgbGreen;
 pLogPal->palPalEntry[i].peBlue = pDibQuad->rgbBlue;
 pLogPal->palPalEntry[i].peFlags = 0;
 pDibQuad++;
}
m_hPalette = ::CreatePalette(pLogPal);
delete pLogPal;
return TRUE;
}
BOOL CDib::SetSystemPalette(CDC* pDC)
{
// if the DIB doesn't have a color table, we can use the system's halftone
palette
if(m_nColorTableEntries != 0) return FALSE;
m_hPalette = ::CreateHalftonePalette(pDC->GetSafeHdc());
return TRUE;
}
HBITMAP CDib::CreateBitmap(CDC* pDC)
{
  if (m_dwSizeImage == 0) return NULL;
  HBITMAP hBitmap = ::CreateDIBitmap(pDC->GetSafeHdc(), m_lpBMIH,
      CBM_INIT, m_lpImage, (LPBITMAPINFO) m_lpBMIH, DIB_RGB_COLORS);
  ASSERT(hBitmap != NULL);
  return hBitmap;
}
BOOL CDib::Compress(CDC* pDC, BOOL bCompress /* = TRUE */)
{
// 1. makes GDI bitmap from existing DIB
// 2. makes a new DIB from GDI bitmap with compression
// 3. cleans up the original DIB
// 4. puts the new DIB in the object
if((m_lpBMIH->biBitCount != 4) && (m_lpBMIH->biBitCount != 8)) return FAL
SE
;
 // compression supported only for 4 bpp and 8 bpp DIBs
if(m_hBitmap) return FALSE; // can't compress a DIB Section!
TRACE("Compress: original palette size = %d\n", m_nColorTableEntries);
HDC hdc = pDC->GetSafeHdc();
HPALETTE hOldPalette = ::SelectPalette(hdc, m_hPalette, FALSE);
HBITMAP hBitmap; // temporary
if((hBitmap = CreateBitmap(pDC)) == NULL) return FALSE;
int nSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntri
es;
LPBITMAPINFOHEADER lpBMIH = (LPBITMAPINFOHEADER) new char[nSize];
memcpy(lpBMIH, m_lpBMIH, nSize); // new header
if(bCompress) {
 switch (lpBMIH->biBitCount) {
 case 4:
  lpBMIH->biCompression = BI_RLE4;
  break;
 case 8:
  lpBMIH->biCompression = BI_RLE8;
  break;
 default:
  ASSERT(FALSE);
 }
 // calls GetDIBits with null data pointer to get size of compressed DIB
 if(!::GetDIBits(pDC->GetSafeHdc(), hBitmap, 0, (UINT) lpBMIH->biHeight,

   NULL, (LPBITMAPINFO) lpBMIH, DIB_RGB_COLORS)) {
  AfxMessageBox("Unable to compress this DIB");
  // probably a problem with the color table
  ::DeleteObject(hBitmap);
  delete [] lpBMIH;
  ::SelectPalette(hdc, hOldPalette, FALSE);
  return FALSE;
 }
 if (lpBMIH->biSizeImage == 0) {
  AfxMessageBox("Driver can't do compression");
  ::DeleteObject(hBitmap);
  delete [] lpBMIH;
  ::SelectPalette(hdc, hOldPalette, FALSE);
  return FALSE;
 }
 else {
  m_dwSizeImage = lpBMIH->biSizeImage;
 }
}
else {
 lpBMIH->biCompression = BI_RGB; // decompress
 // figure the image size from the bitmap width and height
 DWORD dwBytes = ((DWORD) lpBMIH->biWidth * lpBMIH->biBitCount) / 32;
 if(((DWORD) lpBMIH->biWidth * lpBMIH->biBitCount) % 32) {
  dwBytes++;
 }
 dwBytes *= 4;
 m_dwSizeImage = dwBytes * lpBMIH->biHeight; // no compression
 lpBMIH->biSizeImage = m_dwSizeImage;
}
// second GetDIBits call to make DIB
LPBYTE lpImage = (LPBYTE) new char[m_dwSizeImage];
VERIFY(::GetDIBits(pDC->GetSafeHdc(), hBitmap, 0, (UINT) lpBMIH->biHeight
,
   lpImage, (LPBITMAPINFO) lpBMIH, DIB_RGB_COLORS));
  TRACE("dib successfully created - height = %d\n", lpBMIH->biHeight);
::DeleteObject(hBitmap);
Empty();
m_nBmihAlloc = m_nImageAlloc = crtAlloc;
m_lpBMIH = lpBMIH;
m_lpImage = lpImage;
ComputeMetrics();
ComputePaletteSize(m_lpBMIH->biBitCount);
MakePalette();
::SelectPalette(hdc, hOldPalette, FALSE);
TRACE("Compress: new palette size = %d\n", m_nColorTableEntries);
return TRUE;
}
BOOL CDib::Read(CFile* pFile)
{
// 1. read file header to get size of info hdr + color table
// 2. read info hdr (to get image size) and color table
// 3. read image
// can't use bfSize in file header
Empty();
int nCount, nSize;
BITMAPFILEHEADER bmfh;
try {
 nCount = pFile->Read((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER));
 if(nCount != sizeof(BITMAPFILEHEADER)) {
  throw new CException;
 }
 if(bmfh.bfType != 0x4d42) {
  throw new CException;
 }
 nSize = bmfh.bfOffBits - sizeof(BITMAPFILEHEADER);
 m_lpBMIH = (LPBITMAPINFOHEADER) new char[nSize];
 m_nBmihAlloc = m_nImageAlloc = crtAlloc;
 nCount = pFile->Read(m_lpBMIH, nSize); // info hdr & color table
 ComputeMetrics();
 ComputePaletteSize(m_lpBMIH->biBitCount);
 MakePalette();
 m_lpImage = (LPBYTE) new char[m_dwSizeImage];
 nCount = pFile->Read(m_lpImage, m_dwSizeImage); // image only
}
catch(CException* pe) {
 AfxMessageBox("Read error");
 pe->Delete();
 return FALSE;
}
return TRUE;
}
BOOL CDib::ReadSection(CFile* pFile, CDC* pDC /* = NULL */)
{
// new function reads BMP from disk and creates a DIB section
//  allows modification of bitmaps from disk
// 1. read file header to get size of info hdr + color table
// 2. read info hdr (to get image size) and color table
// 3. create DIB section based on header parms
// 4. read image into memory that CreateDibSection allocates
Empty();
int nCount, nSize;
BITMAPFILEHEADER bmfh;
try {
 nCount = pFile->Read((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER));
 if(nCount != sizeof(BITMAPFILEHEADER)) {
  throw new CException;
 }
 if(bmfh.bfType != 0x4d42) {
  throw new CException;
 }
 nSize = bmfh.bfOffBits - sizeof(BITMAPFILEHEADER);
 m_lpBMIH = (LPBITMAPINFOHEADER) new char[nSize];
 m_nBmihAlloc = crtAlloc;
 m_nImageAlloc = noAlloc;
 nCount = pFile->Read(m_lpBMIH, nSize); // info hdr & color table
 if(m_lpBMIH->biCompression != BI_RGB) {
  throw new CException;
 }
 ComputeMetrics();
 ComputePaletteSize(m_lpBMIH->biBitCount);
 MakePalette();
 UsePalette(pDC);
 m_hBitmap = ::CreateDIBSection(pDC->GetSafeHdc(), (LPBITMAPINFO) m_lpBMIH,

 
  DIB_RGB_COLORS, (LPVOID*) &m_lpImage, NULL, 0);
 ASSERT(m_lpImage != NULL);
 nCount = pFile->Read(m_lpImage, m_dwSizeImage); // image only
}
catch(CException* pe) {
 AfxMessageBox("ReadSection error");
 pe->Delete();
 return FALSE;
}
return TRUE;
}
BOOL CDib::Write(CFile* pFile)
{
BITMAPFILEHEADER bmfh;
bmfh.bfType = 0x4d42; // 'BM'
int nSizeHdr = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEn
tries;
bmfh.bfSize = 0;
// bmfh.bfSize = sizeof(BITMAPFILEHEADER) + nSizeHdr + m_dwSizeImage;
// meaning of bfSize open to interpretation (bytes, words, dwords?) -- we w
on't use it
bmfh.bfReserved1 = bmfh.bfReserved2 = 0;
bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
  sizeof(RGBQUAD) * m_nColorTableEntries;
try {
 pFile->Write((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER));
 pFile->Write((LPVOID) m_lpBMIH, nSizeHdr);
 pFile->Write((LPVOID) m_lpImage, m_dwSizeImage);
}
catch(CException* pe) {
 pe->Delete();
 AfxMessageBox("write error");
 return FALSE;
}
return TRUE;
}
void CDib::Serialize(CArchive& ar)
{
DWORD dwPos;
dwPos = ar.GetFile()->GetPosition();
TRACE("CDib::Serialize -- pos = %d\n", dwPos);
ar.Flush();
dwPos = ar.GetFile()->GetPosition();
TRACE("CDib::Serialize -- pos = %d\n", dwPos);
if(ar.IsStoring()) {
 Write(ar.GetFile());
}
else {
 Read(ar.GetFile());
}
}
// helper functions
void CDib::ComputePaletteSize(int nBitCount)
{
if((m_lpBMIH == NULL) || (m_lpBMIH->biClrUsed == 0)) {
 switch(nBitCount) {
  case 1:
  m_nColorTableEntries = 2;
  break;
  case 4:
  m_nColorTableEntries = 16;
  break;
  case 8:
  m_nColorTableEntries = 256;
  break;
  case 16:
  case 24:
  case 32:
  m_nColorTableEntries = 0;
  break;
  default:
  ASSERT(FALSE);
 }
}
else {
 m_nColorTableEntries = m_lpBMIH->biClrUsed;
}
ASSERT((m_nColorTableEntries >= 0) && (m_nColorTableEntries <= 256));
}
void CDib::ComputeMetrics()
{
if(m_lpBMIH->biSize != sizeof(BITMAPINFOHEADER)) {
 TRACE("Not a valid Windows bitmap -- probably an OS/2 bitmap\n");
 throw new CException;
}
m_dwSizeImage = m_lpBMIH->biSizeImage;
if(m_dwSizeImage == 0) {
 DWORD dwBytes = ((DWORD) m_lpBMIH->biWidth * m_lpBMIH->biBitCount) / 32;

 if(((DWORD) m_lpBMIH->biWidth * m_lpBMIH->biBitCount) % 32) {
  dwBytes++;
 }
 dwBytes *= 4;
 m_dwSizeImage = dwBytes * m_lpBMIH->biHeight; // no compression
}
m_lpvColorTable = (LPBYTE) m_lpBMIH + sizeof(BITMAPINFOHEADER);
}
void CDib::Empty()
{
// this is supposed to clean up whatever is in the DIB
DetachMapFile();
if(m_nBmihAlloc == crtAlloc) {
 delete [] m_lpBMIH;
}
else if(m_nBmihAlloc == heapAlloc) {
 ::GlobalUnlock(m_hGlobal);
 ::GlobalFree(m_hGlobal);
}
if(m_nImageAlloc == crtAlloc) delete [] m_lpImage;
if(m_hPalette != NULL) ::DeleteObject(m_hPalette);
if(m_hBitmap != NULL) ::DeleteObject(m_hBitmap);
m_nBmihAlloc = m_nImageAlloc = noAlloc;
m_hGlobal = NULL;
m_lpBMIH = NULL;
m_lpImage = NULL;
m_lpvColorTable = NULL;
m_nColorTableEntries = 0;
m_dwSizeImage = 0;
m_lpvFile = NULL;
m_hMap = NULL;
m_hFile = NULL;
m_hBitmap = NULL;
m_hPalette = NULL;
}
void CDib::DetachMapFile()
{
if(m_hFile == NULL) return;
::UnmapViewOfFile(m_lpvFile);
::CloseHandle(m_hMap);

::CloseHandle(m_hFile);
m_hFile = NULL;
}