680 lines
13 KiB
C++
680 lines
13 KiB
C++
|
|
/*************************************************
|
|
* blockdoc.cpp *
|
|
* *
|
|
* Copyright (C) 1995-1999 Microsoft Inc. *
|
|
* *
|
|
*************************************************/
|
|
|
|
// blockdoc.cpp : implementation of the CBlockDoc class
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include <imm.h>
|
|
#include "cblocks.h"
|
|
#include "dib.h"
|
|
#include "dibpal.h"
|
|
#include "spriteno.h"
|
|
#include "sprite.h"
|
|
#include "phsprite.h"
|
|
#include "myblock.h"
|
|
#include "splstno.h"
|
|
#include "spritlst.h"
|
|
#include "osbview.h"
|
|
#include "blockvw.h"
|
|
#include "slot.h"
|
|
#include "mainfrm.h"
|
|
#include "statis.h"
|
|
#include "wave.h"
|
|
#include "blockdoc.h"
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char BASED_CODE THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
CBitmap m_bmBlock;
|
|
long GScore=0;
|
|
extern CString GHint;
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CBlockDoc
|
|
|
|
IMPLEMENT_DYNCREATE(CBlockDoc, CDocument)
|
|
|
|
BEGIN_MESSAGE_MAP(CBlockDoc, CDocument)
|
|
//{{AFX_MSG_MAP(CBlockDoc)
|
|
ON_COMMAND(ID_OPTION_SIZE_12x10, OnOPTIONSIZE12x10)
|
|
ON_COMMAND(ID_OPTION_SIZE_16x16, OnOPTIONSIZE16x16)
|
|
ON_COMMAND(ID_OPTION_SIZE_4x4, OnOPTIONSIZE4x4)
|
|
ON_COMMAND(ID_TEST_SOUND, OnTestSound)
|
|
ON_COMMAND(ID_OPTION_BEGINER, OnOptionBeginer)
|
|
ON_UPDATE_COMMAND_UI(ID_OPTION_BEGINER, OnUpdateOptionBeginer)
|
|
ON_COMMAND(ID_OPTION_EXPERT, OnOptionExpert)
|
|
ON_UPDATE_COMMAND_UI(ID_OPTION_EXPERT, OnUpdateOptionExpert)
|
|
ON_UPDATE_COMMAND_UI(ID_OPTION_ORDINARY, OnUpdateOptionOrdinary)
|
|
ON_COMMAND(ID_OPTION_ORDINARY, OnOptionOrdinary)
|
|
ON_COMMAND(ID_OPTION_SOUND, OnOptionSound)
|
|
ON_UPDATE_COMMAND_UI(ID_OPTION_SOUND, OnUpdateOptionSound)
|
|
ON_COMMAND(ID_FILE_STATISTIC, OnFileStatistic)
|
|
ON_COMMAND(IDM_TEST, OnTest)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CBlockDoc construction/destruction
|
|
CBlockDoc::CBlockDoc()
|
|
{
|
|
m_pBkgndDIB = NULL;
|
|
m_nRow = 10;
|
|
m_nCol = 12;
|
|
m_nRowHeight = 32;
|
|
m_nColWidth = 32;
|
|
m_pSlotManager = NULL;
|
|
m_bSound = TRUE;
|
|
m_nExpertise = LEVEL_BEGINNER;
|
|
m_pdibArrow = NULL;
|
|
m_bmBlock.LoadBitmap(IDB_BLOCK);
|
|
}
|
|
|
|
CBlockDoc::~CBlockDoc()
|
|
{
|
|
if (m_pBkgndDIB) {
|
|
delete m_pBkgndDIB;
|
|
}
|
|
|
|
m_SpriteList.RemoveAll();
|
|
|
|
if (m_pSlotManager)
|
|
delete m_pSlotManager;
|
|
}
|
|
|
|
char* CBlockDoc::GetChar()
|
|
{
|
|
int Hi;
|
|
int Lo;
|
|
|
|
static char szBuf[4];
|
|
switch (m_nExpertise)
|
|
{
|
|
case LEVEL_EXPERT:
|
|
{
|
|
BOOL bAgain = FALSE;
|
|
int nSafeCount = 0;
|
|
do
|
|
{
|
|
Hi = 0xA4 + MyRand() % (0xF9-0xA4);
|
|
if ((Hi >= 0xC6) && (Hi <= 0xC8))
|
|
{
|
|
nSafeCount++;
|
|
if (nSafeCount > 5)
|
|
{
|
|
Hi = 0xA4;
|
|
bAgain = FALSE;
|
|
}
|
|
else
|
|
bAgain = TRUE;
|
|
}
|
|
|
|
} while (bAgain);
|
|
}
|
|
break;
|
|
case LEVEL_ORDINARY:
|
|
Hi = 0xA4 + MyRand() % (0xC6 - 0xA4);
|
|
break;
|
|
case LEVEL_BEGINNER:
|
|
Hi = 0xA4 + MyRand() % 4;
|
|
|
|
break;
|
|
}
|
|
Lo = (MyRand() % 2) ? 0x40 + MyRand() % 0x3F :
|
|
0xA1 + MyRand() % 0x5E ;
|
|
|
|
szBuf[0] = (BYTE) Hi;
|
|
szBuf[1] = (BYTE) Lo;
|
|
szBuf[2] = 0;
|
|
return szBuf;
|
|
}
|
|
|
|
// helper to load a ball sprite
|
|
CBlock* CBlockDoc::LoadBlock(UINT idRes, int iMass, int iX, int iY, int iVX, int iVY)
|
|
{
|
|
static int nc=0;
|
|
char* pszBuf=NULL;
|
|
CDC dcMem;
|
|
|
|
dcMem.CreateCompatibleDC(NULL);
|
|
CBitmap* pOldBmp = dcMem.SelectObject(&m_bmBlock);
|
|
pszBuf = GetChar();
|
|
CSize szChar = dcMem.GetTextExtent(pszBuf,lstrlen(pszBuf));
|
|
dcMem.SetBkColor(RGB(192,192,192));
|
|
dcMem.SetTextColor(RGB(0,0,255));
|
|
dcMem.TextOut((GetColWidth()-szChar.cx)/2,(GetRowHeight()-szChar.cy)/2,pszBuf,lstrlen(pszBuf));
|
|
dcMem.SelectObject(pOldBmp);
|
|
dcMem.DeleteDC();
|
|
|
|
CBlock* pBlock = new CBlock;
|
|
|
|
if (!pBlock->Load(&m_bmBlock)) {
|
|
char buf[64];
|
|
sprintf(buf, "Failed to load bitmap\n");
|
|
AfxMessageBox(buf);
|
|
delete pBlock;
|
|
return NULL;
|
|
}
|
|
|
|
|
|
pBlock->SetMass(iMass);
|
|
pBlock->SetPosition(iX, iY);
|
|
pBlock->SetVelocity(iVX, iVY);
|
|
pBlock->SetCode(MAKEWORD(BYTE(pszBuf[1]),BYTE(pszBuf[0])));
|
|
return pBlock;
|
|
UNREFERENCED_PARAMETER(idRes);
|
|
}
|
|
|
|
BOOL m_bsndFire;
|
|
BOOL m_bsndGround;
|
|
BOOL m_bsndHit;
|
|
CWave m_sndHit;
|
|
CWave m_sndGround;
|
|
CWave m_sndFire;
|
|
BOOL CBlockDoc::OnNewDocument()
|
|
{
|
|
if (!CDocument::OnNewDocument())
|
|
return FALSE;
|
|
|
|
m_nSeed = (int)(GetTickCount() % 65536);
|
|
|
|
CBlockView* pView = GetBlockView();
|
|
ASSERT(pView);
|
|
m_SpriteList.m_NotifyObj.SetView(pView);
|
|
|
|
// load the background image
|
|
CDIB* pDIB = new CDIB;
|
|
pDIB->Create(m_nColWidth * m_nCol,m_nRowHeight * m_nRow);
|
|
SetBackground(pDIB);
|
|
|
|
if (sndPlaySound("",SND_SYNC))
|
|
{
|
|
m_bsndFire = m_sndFire.LoadResource(IDR_SNDFIRE);
|
|
m_bsndHit = m_sndHit.LoadResource(IDR_SNDHIT);
|
|
m_bsndGround = m_sndGround.LoadResource(IDR_SNDGROUND);
|
|
}
|
|
else
|
|
{
|
|
m_bsndFire = FALSE;
|
|
m_bsndHit = FALSE;
|
|
m_bsndGround = FALSE;
|
|
}
|
|
|
|
if (m_pSlotManager)
|
|
delete m_pSlotManager;
|
|
m_pSlotManager = new CSlotManager(this);
|
|
|
|
if (m_pdibArrow)
|
|
delete m_pdibArrow;
|
|
CBitmap bmArrow;
|
|
bmArrow.LoadBitmap(IDB_ARROW);
|
|
m_pdibArrow = new CBlock;
|
|
m_pdibArrow->Load(&bmArrow);
|
|
|
|
GScore = 0;
|
|
SetModifiedFlag(FALSE);
|
|
|
|
m_nTotalWords =0;
|
|
m_nTotalHitWords =0;
|
|
m_nMissedHit =0;
|
|
m_nHitInMoving =0;
|
|
m_nHitInStill =0;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CBlockDoc::DeleteContents()
|
|
{
|
|
if (m_pSlotManager)
|
|
{
|
|
delete m_pSlotManager;
|
|
m_pSlotManager = NULL;
|
|
}
|
|
|
|
if (m_pdibArrow)
|
|
{
|
|
delete m_pdibArrow;
|
|
m_pdibArrow = NULL;
|
|
}
|
|
//sndPlaySound(NULL,SND_ASYNC);
|
|
CDocument::DeleteContents();
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CBlockDoc serialization
|
|
|
|
void CBlockDoc::Serialize(CArchive& ar)
|
|
{
|
|
CDocument::Serialize(ar);
|
|
if (ar.IsStoring()) {
|
|
if (m_pBkgndDIB) {
|
|
ar << (DWORD) 1; // say we have a bkgnd
|
|
m_pBkgndDIB->Serialize(ar);
|
|
} else {
|
|
ar << (DWORD) 0; // say we have no bkgnd
|
|
}
|
|
m_SpriteList.Serialize(ar);
|
|
} else {
|
|
DWORD dw;
|
|
// see if we have a background to load
|
|
ar >> dw;
|
|
if (dw != 0) {
|
|
CDIB *pDIB = new CDIB;
|
|
pDIB->Serialize(ar);
|
|
// Attach it to the document
|
|
SetBackground(pDIB);
|
|
}
|
|
// read the sprite list
|
|
m_SpriteList.Serialize(ar);
|
|
SetModifiedFlag(FALSE);
|
|
UpdateAllViews(NULL, 0, NULL);
|
|
}
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CBlockDoc diagnostics
|
|
|
|
#ifdef _DEBUG
|
|
void CBlockDoc::AssertValid() const
|
|
{
|
|
CDocument::AssertValid();
|
|
}
|
|
|
|
void CBlockDoc::Dump(CDumpContext& dc) const
|
|
{
|
|
CDocument::Dump(dc);
|
|
}
|
|
|
|
#endif //_DEBUG
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// helper functions
|
|
|
|
// return a pointer to the off-screen buffered view
|
|
CBlockView* CBlockDoc::GetBlockView()
|
|
{
|
|
POSITION pos;
|
|
pos = GetFirstViewPosition();
|
|
ASSERT(pos);
|
|
CBlockView *pView = (CBlockView *)GetNextView(pos);
|
|
ASSERT(pView);
|
|
ASSERT(pView->IsKindOf(RUNTIME_CLASS(CBlockView)));
|
|
return pView;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CBlockDoc commands
|
|
|
|
// Set a new background DIB
|
|
BOOL CBlockDoc::SetBackground(CDIB* pDIB)
|
|
{
|
|
// Delete any existing sprites
|
|
m_SpriteList.RemoveAll();
|
|
|
|
// Delete any existing background DIB and set the new one
|
|
if (m_pBkgndDIB) delete m_pBkgndDIB;
|
|
m_pBkgndDIB = pDIB;
|
|
|
|
// Tell the view that it needs to create a new buffer
|
|
// and palette
|
|
CBlockView* pView = GetBlockView();
|
|
ASSERT(pView);
|
|
return pView->NewBackground(m_pBkgndDIB);
|
|
}
|
|
|
|
void CBlockDoc::GetSceneRect(CRect* prc)
|
|
{
|
|
if (!m_pBkgndDIB) return;
|
|
m_pBkgndDIB->GetRect(prc);
|
|
}
|
|
|
|
void CBlockDoc::Land()
|
|
{
|
|
m_pSlotManager->Land();
|
|
|
|
}
|
|
|
|
void CBlockDoc::Tick()
|
|
{
|
|
int nSlotNo;
|
|
static BOOL bInLoop = FALSE;
|
|
if (! bInLoop)
|
|
{
|
|
bInLoop = TRUE;
|
|
if ((nSlotNo = m_pSlotManager->GetIdleSlot()) >= 0)
|
|
GenerateBlock(nSlotNo);
|
|
bInLoop = FALSE;
|
|
}
|
|
else
|
|
{
|
|
MessageBeep(0);
|
|
TRACE("****************** Problem \n");
|
|
}
|
|
}
|
|
|
|
void CBlockDoc::GenerateBlock(int nSlotNo)
|
|
{
|
|
int vY=0;
|
|
switch(m_nExpertise)
|
|
{
|
|
case LEVEL_EXPERT:
|
|
vY = 500 + MyRand() % 1000;
|
|
break;
|
|
case LEVEL_ORDINARY:
|
|
vY = 300 + MyRand() % 500;
|
|
break;
|
|
case LEVEL_BEGINNER:
|
|
vY = 100 + MyRand() % 200;
|
|
break;
|
|
default:
|
|
vY = 100 + MyRand() % 1000;
|
|
}
|
|
|
|
CBlock* pBlock = LoadBlock(IDB_BLOCK,MyRand() % 600+100,m_nColWidth*nSlotNo,-m_nRowHeight,0,vY);
|
|
m_SpriteList.Insert(pBlock);
|
|
m_pSlotManager->AddRunningBlock(nSlotNo,pBlock);
|
|
GetBlockView()->NewSprite(pBlock);
|
|
m_nTotalWords++;
|
|
|
|
}
|
|
|
|
void CBlockDoc::GameOver(BOOL bHighScore)
|
|
{
|
|
GetBlockView()->GameOver(bHighScore);
|
|
SoundOver();
|
|
POSITION pPos = m_SpriteList.GetHeadPosition();
|
|
for ( ; pPos; )
|
|
{
|
|
CBlock *pBlock = (CBlock *) m_SpriteList.GetNext(pPos);
|
|
pBlock->Inverse();
|
|
}
|
|
UpdateAllViews(NULL);
|
|
}
|
|
|
|
void CBlockDoc::Promote()
|
|
{
|
|
switch (GSpeed)
|
|
{
|
|
case SPEED_FAST:
|
|
//GetBlockView()->SendMessage(WM_COMMAND,ID_ACTION_SLOW);
|
|
break;
|
|
case SPEED_NORMALFAST:
|
|
GetBlockView()->SendMessage(WM_COMMAND,ID_ACTION_FAST);
|
|
break;
|
|
case SPEED_NORMAL:
|
|
GetBlockView()->SendMessage(WM_COMMAND,ID_ACTION_NORMALFAST);
|
|
break;
|
|
case SPEED_NORMALSLOW:
|
|
GetBlockView()->SendMessage(WM_COMMAND,ID_ACTION_NORMAL);
|
|
break;
|
|
case SPEED_SLOW:
|
|
GetBlockView()->SendMessage(WM_COMMAND,ID_ACTION_NORMALSLOW);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void CBlockDoc::Hit(WORD wCode)
|
|
{
|
|
int nLayer=0;
|
|
CBlock *pBlock=m_pSlotManager->Hit(wCode,nLayer);
|
|
if (pBlock)
|
|
{
|
|
SoundHit();
|
|
m_pdibArrow->Coverage(pBlock);
|
|
if (nLayer > 1)
|
|
{
|
|
m_nHitInMoving++;
|
|
GScore += nLayer;
|
|
}
|
|
else
|
|
{
|
|
GScore++;
|
|
m_nHitInStill++;
|
|
}
|
|
m_nTotalHitWords++;
|
|
}
|
|
else
|
|
{
|
|
SoundFire();
|
|
m_nMissedHit++;
|
|
}
|
|
if ((m_nTotalHitWords+1) % 20 == 0)
|
|
{
|
|
Promote();
|
|
}
|
|
if (GScore > 9999999999L)
|
|
{
|
|
GameOver(TRUE);
|
|
}
|
|
}
|
|
|
|
void CBlockDoc::OnOPTIONSIZE12x10()
|
|
{
|
|
m_nRow = 10;
|
|
m_nCol = 12;
|
|
AfxGetApp()->m_pMainWnd->SendMessage(WM_COMMAND,ID_FILE_NEW);
|
|
}
|
|
|
|
void CBlockDoc::OnOPTIONSIZE16x16()
|
|
{
|
|
m_nRow = 16;
|
|
m_nCol = 16;
|
|
AfxGetApp()->m_pMainWnd->SendMessage(WM_COMMAND,ID_FILE_NEW);
|
|
}
|
|
|
|
void CBlockDoc::OnOPTIONSIZE4x4()
|
|
{
|
|
m_nRow = 4;
|
|
m_nCol = 4;
|
|
AfxGetApp()->m_pMainWnd->SendMessage(WM_COMMAND,ID_FILE_NEW);
|
|
}
|
|
|
|
void CBlockDoc::SoundFire()
|
|
{
|
|
if (!m_bSound)
|
|
return;
|
|
|
|
if (m_bsndFire)
|
|
m_sndFire.Play();
|
|
else
|
|
{
|
|
int tone =1000;
|
|
int time = 1;
|
|
for ( ; tone>100; )
|
|
{
|
|
Beep(tone,time);
|
|
tone -= 50;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CBlockDoc::SoundHit()
|
|
{
|
|
if (!m_bSound)
|
|
return;
|
|
|
|
if (m_bsndHit)
|
|
m_sndHit.Play();
|
|
else
|
|
{
|
|
int tone =900;
|
|
int time = 2;
|
|
for ( ; tone<=1200; )
|
|
{
|
|
Beep(tone,time);
|
|
tone += 50;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CBlockDoc::SoundAppear()
|
|
{
|
|
if (!m_bSound)
|
|
return;
|
|
|
|
int tone =200;
|
|
int time = 1;
|
|
for ( ; time<5; )
|
|
{
|
|
Beep(tone,time);
|
|
(time %2) ? tone +=100 : tone -=50;
|
|
time++;
|
|
}
|
|
|
|
}
|
|
|
|
void CBlockDoc::SoundGround()
|
|
{
|
|
if (!m_bSound)
|
|
return;
|
|
|
|
if (m_bsndGround)
|
|
m_sndGround.Play();
|
|
else
|
|
{
|
|
int tone =1000;
|
|
int time = 1;
|
|
for ( ; time<5; )
|
|
{
|
|
Beep(tone,time);
|
|
tone +=100;
|
|
time++;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void CBlockDoc::SoundOver()
|
|
{
|
|
if (!m_bSound)
|
|
return;
|
|
|
|
MessageBeep(MB_ICONASTERISK );
|
|
int tone[8] = {200,200,252,252,300,300,225,225};
|
|
int time=30;
|
|
for (int j=0; j<5; j++)
|
|
for (int i=1; i<8; i++)
|
|
Beep(tone[i],time);
|
|
}
|
|
|
|
void CBlockDoc::OnTestSound()
|
|
{
|
|
SoundHit();
|
|
}
|
|
|
|
|
|
void CBlockDoc::OnOptionBeginer()
|
|
{
|
|
m_nExpertise = LEVEL_BEGINNER;
|
|
AfxGetApp()->OnIdle(RANK_USER);
|
|
}
|
|
|
|
void CBlockDoc::OnUpdateOptionBeginer(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(m_nExpertise == LEVEL_BEGINNER ? 1 : 0);
|
|
}
|
|
|
|
void CBlockDoc::OnOptionExpert()
|
|
{
|
|
m_nExpertise = LEVEL_EXPERT;
|
|
AfxGetApp()->OnIdle(RANK_USER);
|
|
}
|
|
|
|
void CBlockDoc::OnUpdateOptionExpert(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(m_nExpertise == LEVEL_EXPERT ? 1 : 0);
|
|
}
|
|
|
|
void CBlockDoc::OnOptionOrdinary()
|
|
{
|
|
m_nExpertise = LEVEL_ORDINARY;
|
|
AfxGetApp()->OnIdle(RANK_USER);
|
|
}
|
|
|
|
void CBlockDoc::OnUpdateOptionOrdinary(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(m_nExpertise == LEVEL_ORDINARY ? 1 : 0);
|
|
}
|
|
|
|
void CBlockDoc::OnOptionSound()
|
|
{
|
|
m_bSound = ! m_bSound;
|
|
|
|
|
|
}
|
|
|
|
void CBlockDoc::OnUpdateOptionSound(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(m_bSound ? 1 : 0);
|
|
}
|
|
|
|
void CBlockDoc::OnFileStatistic()
|
|
{
|
|
CStatisticDlg sta(this);
|
|
GetBlockView()->SetSpeed(0);
|
|
sta.DoModal();
|
|
GetBlockView()->SetSpeed(GSpeed);
|
|
}
|
|
|
|
void CBlockDoc::Remove(CBlock* pBlock)
|
|
{
|
|
m_SpriteList.Remove(pBlock);
|
|
delete pBlock;
|
|
}
|
|
|
|
WORD CBlockDoc::GetFocusChar(CPoint pt)
|
|
{
|
|
POSITION pPos = m_SpriteList.GetHeadPosition();
|
|
for (;pPos; )
|
|
{
|
|
CBlock* pBlock = (CBlock*) m_SpriteList.GetNext(pPos);
|
|
CRect rc = CRect(pBlock->GetX(),pBlock->GetY(),pBlock->GetX()+m_nColWidth,pBlock->GetY()+m_nRowHeight);
|
|
if (rc.PtInRect(pt))
|
|
return (pBlock->GetCode());
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
#define MAX_COMP 10
|
|
#define MAX_KEY 5
|
|
|
|
BOOL CBlockDoc::GetKeyStroke(WORD wCode)
|
|
{
|
|
HKL hkl = GetKeyboardLayout(0);
|
|
if ( hkl == 0 || !ImmIsIME(hkl) )
|
|
return FALSE;
|
|
|
|
HIMC himc = ImmGetContext(GetBlockView()->GetSafeHwnd());
|
|
char buf[sizeof(CANDIDATELIST)+(sizeof(DWORD) + sizeof(WORD) * MAX_KEY + sizeof(TCHAR) ) * MAX_COMP];
|
|
char lpsrc[3];
|
|
lpsrc[0] = HIBYTE(wCode);
|
|
lpsrc[1] = LOBYTE(wCode);
|
|
lpsrc[2] = 0;
|
|
UINT rc = ImmGetConversionList( hkl, himc,
|
|
lpsrc, (CANDIDATELIST *)buf,
|
|
(UINT)sizeof(buf),
|
|
GCL_REVERSECONVERSION );
|
|
ImmReleaseContext(GetBlockView()->GetSafeHwnd(),himc);
|
|
if (rc == 0)
|
|
return FALSE;
|
|
if (((CANDIDATELIST *) buf)->dwCount == 0)
|
|
return FALSE;
|
|
|
|
GHint = CString(buf+ ((CANDIDATELIST *) buf)->dwOffset[0]);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CBlockDoc::OnTest()
|
|
{
|
|
|
|
}
|