2007年10月31日星期三

用VC设计托盘图标程序

 在Windows操作系统中,任务栏的右边(托盘)会常驻几个图标,如输入法切换图标、音量控制图标等,此外我们还经常遇到具有托盘图标的软件,如金山词霸、实时监测功能的杀毒软件等。这些软件在后台运行,通常不占用太多的屏幕资源,只在通知栏上放一个小小的标志,必要时我们可以通过用鼠标点击图标对其进行选单操作或激活其主窗口。有时我们自己编写的程序也希望有类似的效果,本文将详细地介绍用VC设计托盘图标程序的方法。


  一、 NOTIFYICONDATA结构


  NOTIFYICONDATA结构包含了系统用来处理托盘图标的信息,它包括选择的图标、回调消息、提示消息和图标对应的窗口等内容。其定义为:

  typedef struct—NOTIFYICONDATA {

  DWORD cbSize;

  //以字节为单位的这个结构的大小

  HWND hWnd;

  //接收托盘图标通知消息的窗口句柄

  UINT uID;

  //应用程序定义的该图标的ID号

  UINT uFlags;

  //设置该图标的属性

  UINT uCallbackMessage;

  //应用程序定义的消息ID号,此消息传递给hWnd

  HICON hIcon; //图标的句柄

  char szTip[64]; //鼠标停留在图标上显示的提示信息

  } NOTIFYICONDATA, PNOTIFYICONDATA;

  该结构中,成员uFlags可以是下列的组合或其中之一:

  NIF_ICON:设置成员hIcon有效

  NIF_MESSAGE:设置成员uCallbackMessage有效

  NIF_TIP:设置成员szTip有效


  二、 Shell_NotifyIcon函数


  全局函数Shell_NotifyIcon()用于在托盘上增加、删除或修改图标。其原型为:

  WINSHELLAPI BOOL WINAPI Shell_NotifyIcon( DWORD dwMessage,PNOTIFYICONDATA pnid);

  Pnid是上面的NOTIFYICONDATA结构的指针。

  dwMessage是被传递的消息,可以是以下消息之一:

  NIM_ADD:增加图标

  NIM_DELETE:删除图标

  NIM_MODIFY:修改图标


  三、 托盘图标程序设计示例


  首先我们用AppWizard创建一个不基于文档和视图结构的应用程序Tray。我们并不想在应用程序启动时显示主窗口,所以需要删除应用程序类CTrayApp中成员函数InitInstance()的以下两句代码:

  pFrame-〉ActivateFrame();

  pFrame-〉ShowWindow(SW_SHOW);

  在CMainFrame类中加入NOTIFYICONDATA结构的保护成员变量m_tnid,并在其OnCreate函数中return语句前加入生成托盘图标的代码:

  m_tnid.cbSize=sizeof(NOTIFYICONDATA);

  m_tnid.hWnd=this-〉m_hWnd;

  m_tnid.uFlags=NIF_MESSAGE|NIF_ICON|NIF_TIP;

  m_tnid.uCallbackMessage=MYWM_NOTIFYICON;

  //用户定义的回调消息

  CString szToolTip;

  szToolTip=_T("托盘图标实例");

  _tcscpy(m_tnid.szTip, szToolTip);

  m_tnid.uID=IDR_MAINFRAME;

  HICON hIcon;

  hIcon=AfxGetApp()-〉LoadIcon(IDR_MAINFRAME);

  m_tnid.hIcon=hIcon;

  ::Shell_NotifyIcon(NIM_ADD,&&m_tnid);

  if(hIcon)::DestroyIcon(hIcon);

  返回消息的ID应在主框架类的头函数中定义:

  #define MYWM_NOTIFYICON WM_USER+1

  为了处理图标返回消息,如鼠标左键双击、鼠标右键单击消息,我们重载WindowProc()函数。此外,我们还希望在主框架窗口最小化时图标不在任务栏的空白区出现,在此函数中同时作相应处理。

  LRESULT CMainFrame::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)

  {

  switch(message){

  case MYWM_NOTIFYICON:

  //如果是用户定义的消息

  if(lParam==WM_LBUTTONDBLCLK){

  //鼠标双击时主窗口出现

  AfxGetApp()-〉m_pMainWnd-〉ShowWindow(SW_SHOW);

  }

  else if(lParam==WM_RBUTTONDOWN){ //鼠标右键单击弹出选单

  CMenu menu;

  menu.LoadMenu(IDR_RIGHT_MENU); //载入事先定义的选单

  CMenupMenu=menu.GetSubMenu(0);

  CPoint pos;

  GetCursorPos(&&pos);

  pMenu-〉TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,pos.x,pos.y,AfxGetMainWnd());

  }

  break;

  case WM_SYSCOMMAND:

  //如果是系统消息

  if(wParam= =SC_MINIMIZE){

  //接收到最小化消息时主窗口隐藏

  AfxGetApp()-〉m_pMainWnd-〉ShowWindow(SW_HIDE);

  return 0;

  }

  break;

  }

  return CFrameWnd::WindowProc(message, wParam, lParam);

  }

  为使应用程序退出时图标消失,映射WM_DESTROY消息,在OnDestroy()函数中加入:

  ::Shell_NotifyIcon(NIM_DELETE,&&m_tnid);

  至此,托盘图标程序的常规功能我们均已实现。我们还可以通过Shell_NotifyIcon()函数的调用实现不同状态下图标的改变。

  本程序在VC++ 6.0、Windows 98/2000 Professional下调试通过。

2007年10月30日星期二

노니터 중심위치를 찾음

CPoint pt;
pt.x = GetSystemMetrics(SM_CXSCREEN)/2 // 모니터 폭의 1/2
pt.y = GetSystemMetrics(SM_CYSCREEN)/2 // 모니터 높이의 1/2

2007年10月29日星期一

OnDrag사용하여 파일복사

BOOL CLeftview::OnDrop(COleDataBbject * pDataObject,DROPEFFECT dropEffect,CPoint point)
{
CString StrFolderName;
HTREEITEM hTargetFolder;
CTreeCtrl& treeCtrl = GetTreeCtrl();
CExplorerTestDoc* pDoc = GetDocument();
hTargetFolder = treeCtrl.GetDropHilightItem();
StrFolderName = GetFullPathName(hTargetFolder);
if(dropEffect == DROPEFFECT_COPY)
{
HGLOBAL globalMem;
CSharedFile sharedFile;
globalMem = Sethandle(globalMem,FALSE);
CArchive ar(&sharedFile, CArchive::load);
GetDocument()->SerializeCopyFiles(ar);
ar.Close();
CopyFilesToFolder(strFolderName);

}
treeCtrl.SelectDropTarget(0);
treeCtrl.SelectItem(treeCtrl.GetSelectedItem())//포커스 환원
return TRUE;

}

//OnDrop()함수는 드래그&드롭에 의해 실제 파일들을 복사해 주는 역할을 한다.따라서 처음 부분에는 현재 드롭된 아이템의 경로
//이름을 알아낸 다음 onDragOver()에서 리턴한 값이 DROPEFFECT_COPY일 때만 선택된 파일들을 해당 아이템에 복사하게 된다.

void CLeftView::CopyFilesToFolder(CString strFolderName)
{
CObList * pFileList;
LIST_VIEW * pListView;
CString strMessage strmessage,strTargetFile,strFileName;
CWaitCursor waitCursor;//파일 복사중에 모래시계 커서로 바꾼다.
pFileList = GetDocument()->GetCopyFileList();
for(POSITION pos = pFileList->GetHeadPosition();pos!=NULL)
{
pListView =(LIST_VIEW*)pFileList->GetNext(pos);
strFileName = pListView->strName;
strTargetFile = strFolderName + strFileName;
if(::CopyFile(pListView->strPath,strTargetFile,TRUE)==FALSE)
{
DWORD dwError =::GetLastError();
strmessage.Format("이 볼더에 이미 %s 파일이 잇습니다.\n파일을 바꾸시겠습니까?",strFileName);
if(MessageBox(strmessage,"파일 바꾸기 확인"),MB_ICONQUESTION|MB_YESNO)==IDYES)
{
dwError = ::GetLastError();
strMessage.Format("'%s'파일 복사 실패",strFileName);
MessageBox(strmessage,"파일 복사",MB_ICONSTOP);
}
}
}
}

//이 함수는 지렬화를 통해 알아낸 파일 리스트를 이용하여 Win32 API인 ::CopyFile()를 호출해서 파일들을 실제로 복사하는 역할을 수행한다,다음은 좌측의 리스트 뷰에서 두 개의 파일을 선택하여 트리 뷰로 드래그&드롭을 하는 모습이다,만약 동일한 파일이 있는 경우 기존 파일의 변경 여부를 묻는 다이얼 로그가 출격된다.

주의 점

*pListView = *(LIST_VIEW*)listCtrl.GetItemData(nItem)

pListView = (LIST_VIEW*)listCtrl.GetItemData(nItem);

새로운 파일 리스트를 나중에서 삭제할 때:
2의 경우 원래 가지고 있었던 파일 리스트의 메모리 포인터를 사용하는것이므로 원래의 파일 리스트도 메모리에서 삭제 된다.

원래의 파일 리스트는 항상 메모리에 있어야 함으로 1번과 같이 메모리 포인터가 아닌 메모리에 저장되어 있는 파일의 정보를 새로 복사하여ㅕ 나중에 이 리스트를 삭제하더라도 원래의 리스트는 손상되지 않는다.

ConvertWCtoMB

HRESULT CSyncSongDlg::ConvertWCtoMB(LPWSTR *ppwszInString, LPSTR *ptszOutString)
{
if( ppwszInString == NULL || ptszOutString == NULL )
{
return E_INVALIDARG;
}

HRESULT hr = S_OK;
int nSizeCount = 0;

*ptszOutString = NULL;

do
{
nSizeCount = WideCharToMultiByte(CP_ACP, 0, *ppwszInString, -1, NULL, 0, NULL, NULL);
if( 0 == nSizeCount )
{
hr = HRESULT_FROM_WIN32( GetLastError() );
break;
}

*ptszOutString = new char[nSizeCount]; //memory leak...how??
if( NULL == ptszOutString)
{
hr = HRESULT_FROM_WIN32( GetLastError() );
break;
}

if( 0 == WideCharToMultiByte(CP_ACP, 0, *ppwszInString, -1, *ptszOutString, nSizeCount, NULL, NULL) )
{
hr = HRESULT_FROM_WIN32( GetLastError() );
break;
}

}
while(FALSE);

if( FAILED( hr ) )
{
SAFE_ARRAYDELETE( ptszOutString );
return hr;
}

return hr;
}

리스트 컨트롤의 레포트 형식에서 사용하는 헤더 컨트롤의 컬럼을 추가

BOOL CMyListCtrl::ADDColumn(int nItem,LPCSTR strItem,int nSubItem,int nMask,int nFmt)
{
LV_COLUMN lvc;
lvc.mask =nMask;
lvc.fmt=nFmt;//헤더 컨트롤에 출력될 문자열 포맷 설정
lvc.pszText=(LPSTR)strItem;//출력될 문자열]
lvc.cx=GetStringWidth(lvc.pszText)+15;//컬럴 폭 설정
if(nMask & LVCF_SUBITEM)
{
if(nSubItem!=-1)
lvc.iSubItem = nSubItem;//서브 아이템 설정
else
lvc.iSubItem = nItem;//아이템 설정
}
return insertColumn(nItem,&lvc);//컬럼 추가
}

아이템 크기에 맞게 헤더 컨트롤의 크기를 자동으로 조절

void CMyListCtrl::AutoSize()
{
CHeaderCtrl *pHD=(CHeaderCtrl*)GetDlgItem(0);
pHD->ModifyStyle(0,HDS_HOTTRACK);//헤더 컨틀롤에 핫트래킹 설정
int nCount = pHD->GetItemCount();//컬럼 개수 얻음
for(int i = 0;i SetColumnWidth(i,LVSCW_AUTOSIZE);//컬럼의 폭 설정
}

자신이 직접만든 CMyListCtrl클래스

헤더 파잉레 멤버함수를 추가
BOOL AddItem(int nItem,int nSunItem,LPCSTR strItem,int nImageIndex=-1)//리스트 컨트롤에 아이테 추가

BOOL AddColumn(int nItem,LPCSTR strItem,int nSubItem=-1,int nMask = LVCF_TEXTLVCF_FMTLVCF_WIDTHLVCF_SUBITEM,int nfmt=LVCFMT_LEFT);헤더 컨트롤의 컬럼 설정

BOOL CMyListCtrl::AddItem(int nItem,int nSubItem,LPCSTR strItem,int nImageIndex)
{
LV_ITEM lvitlvit.mask =LVIF_TEXT//아이템에서 텍스트를 사용하기 위한 플래그
lvit.iItem =nItem//아이템의 인덱스lvit.iSubItem = nSubItem;//서브 아이템의 인덱스
lvit.pszText =(LPSTR)stritem;//아이템에 설정할 문자열
if(nImageIndex!=-1)//이미지를 사용하는 경우
{ lvit.mask=LVIF_IMAGE//이미지를 사용하기 위한 플래그 설정
lvit.iImage=nImageIndex;//리스트 컨트롤에서 사용할 이미지 인덱스}
if(nSbuItem==0)return InsertItem(&lvit);//아이템 삽입
return SetItem(&lvit);//서브 아이템 설정}

2007年10月26日星期五

判断某个URL是否有效

bool CUtil::IsReachableURL(CString sURL)
{ CInternetSession Session;
CHttpFile * pFile;
try
{
pFile = (CHttpFile *) Session.OpenURL(sURL);
}

catch (CException * e)

{ e->Delete(); pFile = NULL; } return (pFile != NULL);}

USB摄像头编程

注意包含头文件qedit.h,dshow.h
几个函数如下,其中有一些全局变量,程序写的充忙,也就不整理了。参考了一些资料。
BOOL initVideo(void)
{
AM_MEDIA_TYPE amt;
CoInitialize(NULL); // COM的初期化
// ---- 输入计算的准备 ----
// 搜索输入装置
IBaseFilter *pbf = NULL;
IMoniker * pMoniker = NULL;
ULONG cFetched;
// 制作装置的各个部分
CoCreateInstance( CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
IID_ICreateDevEnum, (void ** ) &pDevEnum);
// 制作视频输入装置的各个部分
IEnumMoniker * pClassEnum = NULL;
pDevEnum -> CreateClassEnumerator(
CLSID_VideoInputDeviceCategory, &pClassEnum, 0);
if (pClassEnum == NULL){
AfxMessageBox("No video device, program exit!");
pDevEnum -> Release();
CoUninitialize();
//OnOK();
return FALSE ;
}
// 取得最初发现的视频输入装置object的接口
pClassEnum -> Next(1, &pMoniker, &cFetched);
pMoniker->BindToObject( 0, 0, IID_IBaseFilter, (void**)&pbf );

// ---- 过虑图像的准备 ----
// 制作过虑图像,取得接口
CoCreateInstance( CLSID_FilterGraph, NULL, CLSCTX_INPROC,
IID_IGraphBuilder, (void **) &pGraph);
pGraph -> QueryInterface( IID_IMediaControl, (LPVOID *) &pMC );
// 把输入图像追加到过虑图像
pGraph -> AddFilter( pbf, L"Video Capture");
// 因为进行了追加所以解除参照的输入图像
pbf -> Release();
// ---- 过虑图像的准备 ----
// 制作过虑图像,取得接口
CoCreateInstance( CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER,
IID_IBaseFilter, (LPVOID *)&pF);
pF -> QueryInterface( IID_ISampleGrabber, (void **)&pGrab );
// 把输入图像追加到过虑图像
ZeroMemory(&amt, sizeof(AM_MEDIA_TYPE));
amt.majortype = MEDIATYPE_Video;
amt.subtype = MEDIASUBTYPE_RGB24;
amt.formattype = FORMAT_VideoInfo;
pGrab -> SetMediaType( &amt );
// 把grubber过虑追加到过虑图像
pGraph -> AddFilter(pF, L"SamGra");
// ---- 输入图像的准备 ----
// 制作输入图像
CoCreateInstance( CLSID_CaptureGraphBuilder2 , NULL, CLSCTX_INPROC,
IID_ICaptureGraphBuilder2, (void **) &pCapture );
// 把过虑图像编入到输入图像
pCapture -> SetFiltergraph( pGraph );
// 输入图像的设定,设定grubber为rendering输出
pCapture -> RenderStream (&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,
pbf, NULL, pF);

// ---- 表示窗口的准备 ----
// 位图信息的取得
pGrab -> GetConnectedMediaType( &amt );
// 获得视频头部的信息
VIDEOINFOHEADER *pVideoHeader = (VIDEOINFOHEADER*)amt.pbFormat;
// 在视频的头部包含位图的信息
// 把位图的信息复制到BITMAPINFO的结构体中
BITMAPINFO BitmapInfo;
ZeroMemory( &BitmapInfo, sizeof(BitmapInfo) );
CopyMemory( &BitmapInfo.bmiHeader, &(pVideoHeader->bmiHeader),
sizeof(BITMAPINFOHEADER));
img00.bih = BitmapInfo.bmiHeader;
long n = img00.bih.biSizeImage;

char s[100];
sprintf(s, "Video Width: %ld Video Height: %ld", img00.bih.biWidth, img00.bih.biHeight);
AfxMessageBox(s);

img00.lpBmpData = (BYTE *)malloc( n );

// ************* 追加 *****************
if (img00.lpBmpData == NULL) {
AfxMessageBox("Insufficient Memory!");
}

img00.hi = (HINSTANCE)GetWindowLong( HWND_DESKTOP, GWL_HINSTANCE );
return true;
}
void initGraphic(void)
{
// 把位图的信息复制到BITMAPINFO的结构体中
BITMAPINFO BitmapInfo;
ZeroMemory( &BitmapInfo, sizeof(BitmapInfo) );
CopyMemory( &BitmapInfo.bmiHeader, &img00.bih,
sizeof(BITMAPINFOHEADER));
img01.bih = BitmapInfo.bmiHeader;
long n = img01.bih.biSizeImage;
img01.lpBmpData = (BYTE *)malloc( n );

// **************** 追加 ******************
if (img01.lpBmpData == NULL) {
printf("Insufficient memory available (img01.lpBmpData)\n");
}
img01.hi = (HINSTANCE)GetWindowLong( HWND_DESKTOP, GWL_HINSTANCE );
}
void closeVideo(void)
{
// 接口的解除
pMC -> Release();
pDevEnum -> Release();
pGraph -> Release();
pCapture -> Release();

CoUninitialize();
free( img00.lpBmpData );
}

输入Gb字符,返回Big5字符

//---------------------------------------------------------------------------
//函数输入Gb字符,返回Big5字符
//---------------------------------------------------------------------------
AnsiString __fastcall Gb2Big(AnsiString sGb)
{
char* pszGbt=NULL; //Gb编码的繁体字符
char* pszGbs=NULL; //Gb编码的简体字符
wchar_t* wszUnicode=NULL; //Unicode编码的字符
char* pszBig5=NULL; //Big5编码的字符
AnsiString sBig5; //返回的字符串
int iLen=0; //需要转换的字符数

pszGbs=sGb.c_str(); //读入需要转换的字符参数

//计算转换的字符数
iLen=MultiByteToWideChar (936, 0, pszGbs, -1, NULL,0) ;

//给pszGbt分配内存
pszGbt=new char[iLen*2+1];
//转换Gb码简体到Gb码繁体,使用API函数LCMapString
LCMapString(0x0804,LCMAP_TRADITIONAL_CHINESE, pszGbs, -1, pszGbt, iLen*2);

//给wszUnicode分配内存
wszUnicode=new wchar_t[iLen+1];
//转换Gb码到Unicode码,使用了API函数MultiByteToWideChar
MultiByteToWideChar (936, 0, pszGbt, -1, wszUnicode,iLen);

//计算转换的字符数
iLen=WideCharToMultiByte (950, 0, (PWSTR) wszUnicode, -1, NULL,0, NULL, NULL) ;
//给pszBig5分配内存
pszBig5=new char[iLen+1];
//转换Unicode码到Big5码,使用API函数WideCharToMultiByte
WideCharToMultiByte (950, 0, (PWSTR) wszUnicode, -1, pszBig5,iLen, NULL, NULL) ;

//返回Big5码字符
sBig5=pszBig5;

//释放内存
delete [] wszUnicode;
delete [] pszGbt;
delete [] pszBig5;

return sBig5;
}

输入Big5字符,返回Gb简体字符

//---------------------------------------------------------------------------
//函数输入Big5字符,返回Gb简体字符
//---------------------------------------------------------------------------
AnsiString __fastcall Big2Gb(AnsiString sBig)
{
char* pszBig5=NULL; //Big5编码的字符
wchar_t* wszUnicode=NULL; //Unicode编码的字符
char* pszGbt=NULL; //Gb编码的繁体字符
char* pszGbs=NULL; //Gb编码的简体字符
AnsiString sGb; //返回的字符串
int iLen=0; //需要转换的字符数

pszBig5=sBig.c_str(); //读入需要转换的字符参数

//计算转换的字符数
iLen=MultiByteToWideChar (950, 0, pszBig5, -1, NULL,0) ;
//给wszUnicode分配内存
wszUnicode=new wchar_t[iLen+1];
//转换Big5码到Unicode码,使用了API函数MultiByteToWideChar
MultiByteToWideChar (950, 0, pszBig5, -1, wszUnicode,iLen);

//计算转换的字符数
iLen=WideCharToMultiByte (936, 0, (PWSTR) wszUnicode, -1, NULL,0, NULL, NULL) ;
//给pszGbt分配内存
pszGbt=new char[iLen+1];
//给pszGbs分配内存
pszGbs=new char[iLen+1];
//转换Unicode码到Gb码繁体,使用API函数WideCharToMultiByte
WideCharToMultiByte (936, 0, (PWSTR) wszUnicode, -1, pszGbt,iLen, NULL, NULL) ;

//转换Gb码繁体到Gb码简体,使用API函数LCMapString
LCMapString(0x0804,LCMAP_SIMPLIFIED_CHINESE, pszGbt, -1, pszGbs, iLen);

//返回Gb码简体字符
sGb=pszGbs;

//释放内存
delete [] wszUnicode;
delete [] pszGbt;
delete [] pszGbs;

return sGb;
}

2007年10月25日星期四

BASSFX 파라미터 설정

void CEqualizerDlg::UpdateFX(int b){ int v = m_nArrEQ[b] / 50; CSyncSongDlg* pDlg = (CSyncSongDlg*)AfxGetMainWnd();
if (b<10)>m_BASSAudio.BASS_FXGetParameters(fx[b],&paramEQ); paramEQ.fGain=(float)10.0-v; pDlg->m_BASSAudio.BASS_FXSetParameters(fx[b],&paramEQ); } else { BASS_FXREVERB paramEQ; pDlg->m_BASSAudio.BASS_FXGetParameters(fx[10],&paramEQ); paramEQ.fReverbMix=(float)-0.012*v*v*v; pDlg->m_BASSAudio.BASS_FXSetParameters(fx[10],&paramEQ); }}




void CEqualizerDlg::SetBassFXParam(/*HSTREAM hStream*/){ //m_hStream = hStream; BASS_FXPARAMEQ paramEQ;
CSyncSongDlg* pDlg = (CSyncSongDlg*)AfxGetMainWnd();
fx[0]=pDlg->m_BASSAudio.BASS_ChannelSetFX(pDlg->m_BASSAudio.m_hStream,BASS_FX_PARAMEQ,0); //return effect's handle fx[1]=pDlg->m_BASSAudio.BASS_ChannelSetFX(pDlg->m_BASSAudio.m_hStream,BASS_FX_PARAMEQ,0); fx[2]=pDlg->m_BASSAudio.BASS_ChannelSetFX(pDlg->m_BASSAudio.m_hStream,BASS_FX_PARAMEQ,0); fx[3]=pDlg->m_BASSAudio.BASS_ChannelSetFX(pDlg->m_BASSAudio.m_hStream,BASS_FX_PARAMEQ,0); fx[4]=pDlg->m_BASSAudio.BASS_ChannelSetFX(pDlg->m_BASSAudio.m_hStream,BASS_FX_PARAMEQ,0); fx[5]=pDlg->m_BASSAudio.BASS_ChannelSetFX(pDlg->m_BASSAudio.m_hStream,BASS_FX_PARAMEQ,0); fx[6]=pDlg->m_BASSAudio.BASS_ChannelSetFX(pDlg->m_BASSAudio.m_hStream,BASS_FX_PARAMEQ,0); fx[7]=pDlg->m_BASSAudio.BASS_ChannelSetFX(pDlg->m_BASSAudio.m_hStream,BASS_FX_PARAMEQ,0); fx[8]=pDlg->m_BASSAudio.BASS_ChannelSetFX(pDlg->m_BASSAudio.m_hStream,BASS_FX_PARAMEQ,0); fx[9]=pDlg->m_BASSAudio.BASS_ChannelSetFX(pDlg->m_BASSAudio.m_hStream,BASS_FX_PARAMEQ,0);
paramEQ.fGain = 0; //-15 TO 15 paramEQ.fBandwidth=18; //1 TO 36
paramEQ.fCenter=80; //HERTZ 80 TO 16000 pDlg->m_BASSAudio.BASS_FXSetParameters(fx[0],&paramEQ); paramEQ.fCenter=170; pDlg->m_BASSAudio.BASS_FXSetParameters(fx[1],&paramEQ); paramEQ.fCenter=310; pDlg->m_BASSAudio.BASS_FXSetParameters(fx[2],&paramEQ); paramEQ.fCenter=600; pDlg->m_BASSAudio.BASS_FXSetParameters(fx[3],&paramEQ);
paramEQ.fCenter=1000; pDlg->m_BASSAudio.BASS_FXSetParameters(fx[4],&paramEQ);
paramEQ.fCenter=3000; pDlg->m_BASSAudio.BASS_FXSetParameters(fx[5],&paramEQ);
paramEQ.fCenter=6000; pDlg->m_BASSAudio.BASS_FXSetParameters(fx[6],&paramEQ);
paramEQ.fCenter=8000; pDlg->m_BASSAudio.BASS_FXSetParameters(fx[7],&paramEQ);
paramEQ.fCenter=12000; pDlg->m_BASSAudio.BASS_FXSetParameters(fx[8],&paramEQ);
paramEQ.fCenter=14000; pDlg->m_BASSAudio.BASS_FXSetParameters(fx[9],&paramEQ);
if(m_bUseEQ) //EQ를 사용할 경우에만 적용 { UpdateFX(0); UpdateFX(1); UpdateFX(2); UpdateFX(3); UpdateFX(4); UpdateFX(5); UpdateFX(6); UpdateFX(7); UpdateFX(8); UpdateFX(9); }}

2007年10月24日星期三

用VC实现竖写汉字的方法

中国人自古就有自右至左、从上到下书写汉字的习惯。而当我们在自己所编写的应用程序中使用输出函数输出的总是自左至右的横排文字。有没有可能在我们的应用程序中实现竖写汉字的效果呢?笔者偶然发现了一种利用VC实现竖写汉字效果的方法,现在就把它介绍给大家。   
Windows系统内置了许多名称以“@”开头的字集,这些字集有一个共同的特点,即其所包含的文字全都是平躺着的(字头朝左,字底朝右)。如果我们能将这些字逆时针旋转270度后再显示出来,就可以达到实现竖写汉字效果的目的了。   要使文字发生旋转,我们只需创建一个逻辑字体并设定该逻辑字体的显示角度,再设定其字体名称为一个以“@”开头的字集的名称即可。我们可以采用两种方式创建逻辑字体。   其一,用CFont类的成员函数CreateFont直接创建逻辑字体。CreateFont的参数定义如下: BOOL CreateFont( int nHeight, //字体的高度 int nWidth, //字体的宽度 int nEscapement, //字体显示的角度 int nOrientation, //字体的角度 int nWeight, //字体的磅数 BYTE bItalic, //斜体字体 BYTE bUnderline, //带下划线的字体 BYTE cStrikeOut, //带删除线的字体 BYTE nCharSet, //所需的字符集 BYTE nOutPrecision, //输出的精度 BYTE nClipPrecision, //裁减的精度 BYTE nQuality, //逻辑字体与输出设备的实际 //字体之间的精度 BYTE nPitchAndFamily, //字体间距和字体集 LPCTSTR lpszFacename //字体名称 );   其中nEscapement单位为0.1角度,方向为逆时针,所以为了使平躺的字立起来应设定其值为2700,lpszFacename则赋以“@”开头的字集的名称,如“@system”。   其二,利用LOGFONT结构,将该结构作为参数调用CFont类的成员函数CreateFontIndirect创建逻辑字体。LOGFONT结构通常被用来描述一种逻辑字体,结构内的各变量分别代表逻辑字体的各个属性,这些变量与函数CreateFont的参数相同。其结构如下: typedef struct tagLOGFONT { // lf           LONG lfHeight; //字体的高度          LONG lfWidth; //字体的宽度          LONG lfEscapement; //字体显示的角度           LONG lfOrientation; //字体的角度          LONG lfWeight; //字体的磅数          BYTE lfItalic; //斜体字体          BYTE lfUnderline; //带下划线的字体          BYTE lfStrikeOut; //带删除线的字体          BYTE lfCharSet; //所需的字符集          BYTE lfOutPrecision; //输出的精度          BYTE lfClipPrecision; //裁减的精度          BYTE lfQuality; //逻辑字体与输出设备的 //实际字体之间的精度          BYTE lfPitchAndFamily; //字体间距和字体集          TCHAR lfFaceName[LF_FACESIZE]; //字体名称} LOGFONT;   下面我们就以一个示例来说明竖写汉字的实现方法:   1.建立一个MFC AppWizard(exe)应用工程CHNfont。在MFC AppWizard向导的第一步中选择Single Document,再点击按键Finish->OK完成工程的建立。   2.在CMainFrame::OnCreate函数中添加如下代码,使窗体最大化。AfxGetMainWnd()->ShowWindow(SW_SHOWMAXIMIZED);   3.添加如下代码实现竖写功能。 void CChildView::OnPaint() {CPaintDC dc(this);// device context for painting/////// 利用CFont::CreateFont(...)函数实现竖写汉字////////CFont myFont; //创建字体对象//创建逻辑字体myFont.CreateFont(              56, //字体高度(旋转后的字体宽度)=56               20, //字体宽度(旋转后的字体高度)=20              2700, //字体显示角度=270°              0, //nOrientation=0              10, //字体磅数=10              FALSE, //非斜体              FALSE, //无下划线              FALSE, //无删除线              DEFAULT_CHARSET, //使用缺省字符集              OUT_DEFAULT_PRECIS, //缺省输出精度              CLIP_DEFAULT_PRECIS,//缺省裁减精度               DEFAULT_QUALITY, //nQuality=缺省值              DEFAULT_PITCH, //nPitchAndFamily=缺省值              "@system"); //字体名=@systemCFont *pOldFont=dc.SelectObject(&myFont);//选入设备描述表CRect rtClient;GetClientRect(rtClient); //获取客户区尺寸、位置信息//在客户区适当位置输出文字dc.TextOut(rtClient.Width()/2+30,rtClient.Height()/8, "无边落木萧萧下");dc.SelectObject(pOldFont); //将myFont从设备环境中分离myFont.DeleteObject(); //删除myFont对象/////////// 利用LOGFONT结构实现竖写汉字//////////////LOGFONT lf; //定义字体结构lf.lfWeight=10; //字体磅数=10lf.lfHeight=56; //字体高度(旋转后的字体宽度)=56 lf.lfWidth=20; //字体宽度(旋转后的字体高度)=20lf.lfUnderline=FALSE; //无下划线lf.lfStrikeOut=FALSE; //无删除线lf.lfItalic=FALSE; //非斜体lf.lfEscapement=2700; //字体显示角度=270°lf.lfCharSet=DEFAULT_CHARSET; //使用缺省字符集 strcpy(lf.lfFaceName,"@system"); //字体名=@system CFont myLogFont; //定义字体对象myLogFont.CreateFontIndirect(&lf); //创建逻辑字体pOldFont=dc.SelectObject(&myLogFont);//选入设备描述表//在客户区适当位置输出文字dc.TextOut(rtClient.Width()/2-30,rtClient.Height()/8, "不尽长江滚滚来");dc.SelectObject(pOldFont); //将myFont从设备环境中分离myLogFont.DeleteObject(); //删除myLogFont对象 } 4.编译连接,运行。 以上实例在Windows98下,以VC++6.0编译通过。

2007年10月22日星期一

Mdf파일

经常更新和优化的数据库可以以更快的速度运行。然而,将数据库直接从一个比较小的磁盘转移到另一个比较大的磁盘,这样的想法是不可能实现的。
在转移数据库之前,你必须将数据库断开所有的操作。使用sp_detach_db存储程序可以将数据库从SQL Server 2000分离开来,从而达到数据库的离线操作。同样可以运行另一个存储程序sp_attach_db将数据库重新连接。
Sp_detach_db是一个功能强大的存储程序,它只能由系统管理人员运行。除了具备“分离”功能之外,这一程序在分离数据库之前也自动运行所有表的UPDATE STATISTICS。
以下的范例分离了MyDatabase数据库:
EXEC sp_detach_db 'MyDatabase'
现在可以转移我们的数据库到一个新的磁盘并重新连接它们。连接数据库操作可能比较复杂,除了提供数据库名称,你可以选择SQL Server数据库文件的位置。
在以下的范例中,我们可以从一个新位置D:AnyFolder:重新连接数据库。
execsp_attach_db 'MyDatabase',@filename1='D:AnyFolderMyDatabase_Data.MDF',@filename2='D:AnyFolderMyDatabase_Log.LDF'

2007年10月21日星期日

기호 삭제

CString CAutoSyncDlg::_Remove_Symbol(CString strData){ int i = 0; int nLen = strData.GetLength(); if(nLen <= 0) return strData;
BYTE *strBuffer; strBuffer = (BYTE*)malloc(strData.GetLength()); memcpy(strBuffer, strData, nLen);
strData.Replace(_T("-"), _T(" ")); strData.Replace(_T("_"), _T(" ")); for(i=0; i < nLen; i++) {
if((strBuffer[i] >= 0xB0) && (strBuffer[i] <= 0xC8) //__한글부분 && (strBuffer[i+1] >= 0xA1) && (strBuffer[i+1] <= 0xFE)) { i++; }else if((strBuffer[i]>= 0xCA) && (strBuffer[i] <= 0xFD) //__한자 해당 부분 && (strBuffer[i+1] >= 0xA1) && (strBuffer[i+1] <= 0xFE)) { i++; }else if(((strBuffer[i]>= 0x41) && (strBuffer[i] <= 0x5A)) //__ 영어 해당 부분 ((strBuffer[i] >= 0x61) && (strBuffer[i] <= 0x7A))) {
}else if((strBuffer[i]>= '0') && (strBuffer[i] <= '9')) { //__숫자 처리 부분 // strData.SetAt(i, ' '); //__숫자는 별도로 처리함.. }else if((strBuffer[i]>= 0xA1) && (strBuffer[i+1] >= 0xA1)) { //__2byte특수문자 부분 strData.SetAt(i, ' '); strData.SetAt(i+1, ' '); i++;
}else { //__1byte 특수문자 strData.SetAt(i, ' '); }
}
strData.Replace(_T(" "), _T(" ")); strData.Replace(_T("'"),_T("")); //strData.Replace("""",""); strData.Replace(_T("\""),_T("")); //edit by sun strData.Replace(_T("&"),_T(""));
free(strBuffer);
return strData;
}

괄호 삭제

CString CAutoSyncDlg::_Remove_Parenthesis(CString strData){
CString strDummy = _T("");
int nTStart, nTEnd; bool bExit = false;
while(!bExit) { //__() 소괄호 제거 nTStart = strData.Find(_T("("), 0); nTEnd = strData.Find(_T(")"), 0);
if(nTStart == -1 nTEnd == -1) { bExit = true; } else { if(nTEnd < nTStart) { bExit = true; } else { strDummy = strData.Mid(nTStart, (nTEnd+1)-nTStart); strData.Replace(strDummy, _T("")); } } }
bExit = false; while(!bExit) {//__[] 대괄호 제거 nTStart = strData.Find(_T("["), 0); nTEnd = strData.Find(_T("]"), 0);
if(nTStart == -1 nTEnd == -1) { bExit = true; } else { if(nTEnd < nTStart) { bExit = true; } else { strDummy = strData.Mid(nTStart, (nTEnd+1)-nTStart); strData.Replace(strDummy, _T("")); } } }
bExit = false; while(!bExit) {//__{} 중괄호 제거 nTStart = strData.Find(_T("{"), 0); nTEnd = strData.Find(_T("}"), 0);
if(nTStart == -1 nTEnd == -1) { bExit = true; } else { if(nTEnd < nTStart) { bExit = true; } else { strDummy = strData.Mid(nTStart, (nTEnd+1)-nTStart); strData.Replace(strDummy, _T("")); } } }

return strData;}

바이러스 검색 다운로드

http://www.lanniao.org/soft/nod32/

下载3和5

폴드

BOOL BrowseFolder(HWND hWnd, char *szFolder){ LPMALLOC ShellMalloc; LPITEMIDLIST idBrowse; BROWSEINFO BrowseInfo; char szDisplayName[MAX_PATH];
if (SHGetMalloc(&ShellMalloc) != NOERROR) { return FALSE; }
BrowseInfo.hwndOwner = hWnd; BrowseInfo.pidlRoot = NULL; BrowseInfo.pszDisplayName = szDisplayName; BrowseInfo.lpszTitle = "请选择背景图片" ; BrowseInfo.ulFlags = BIF_DONTGOBELOWDOMAIN; BrowseInfo.lpfn = NULL; BrowseInfo.lParam = 0;
idBrowse = SHBrowseForFolder(&BrowseInfo);
if (idBrowse == NULL) { return FALSE; } SHGetPathFromIDList(idBrowse, szFolder); ShellMalloc->Free(idBrowse); ShellMalloc->Release(); return TRUE;}

USB꼽힌 상태와 뺀상태

if((nEventType == 32772) (nEventType == 32768))

파일 저장

void CSearchDlg::SaveNPLWhenClose()
{
int nItmeCnt = 0; nItmeCnt = m_PuchaseGrid.GetItemCount(); if(nItmeCnt < 1) return;
CString strRegstr;
strRegstr = theGloval.m_strPuchaseDir + _T("\\PuchaseList.npl");
FILE *fp; fp = _tfopen((LPCTSTR)strRegstr, _T("w+b"));
if(fp == NULL) return;
if(nItmeCnt < 1){ fclose(fp); }else{ CString strArtistName, strTitle,strExpired;// strDummyTime;
CString strPath , strAccessTime;
LVITEM lvi; memset(&lvi, 0, sizeof(LVITEM)); lvi.iItem =0; lvi.mask = LVIF_PARAM;
XLISTCTRLDATA* pXLISTCTRLDATA;
for(int i = 0;i < nItmeCnt; i++){
strTitle = m_PuchaseGrid.GetItemText(i, 2); strArtistName = m_PuchaseGrid.GetItemText(i, 3); strExpired = m_PuchaseGrid.GetItemText(i, 4);
memset(&lvi, 0, sizeof(LVITEM)); lvi.iItem =i; lvi.mask = LVIF_PARAM; VERIFY(::SendMessage(m_PuchaseGrid.m_hWnd, LVM_GETITEM, 0, (LPARAM)&lvi)); pXLISTCTRLDATA = (XLISTCTRLDATA*) lvi.lParam;
strPath = pXLISTCTRLDATA->strPath; strAccessTime = pXLISTCTRLDATA->strAccessDate;

strTitle.Replace(_T("\n"), _T("")); strArtistName.Replace(_T("\n"), _T(""));
_ftprintf(fp, _T("%s%s%s%s%s\n"), strPath, strTitle, strArtistName,strExpired,strAccessTime);
} fclose(fp); }
}

폴드찾기

void CSearchDlg::FolderSearch(CString DirectoyName){ // DWORD MAXFILE = 8192; // TCHAR* pc = new TCHAR[MAXFILE]; DirectoyName += _T("\\*.*");
CFileFind finder; DirectoyName.MakeUpper(); BOOL bWorking = finder.FindFile(DirectoyName);
while (bWorking) { bWorking = finder.FindNextFile(); // skip . and .. files; otherwise, we'd // recur infinitely! if (finder.IsDots()) { continue; } // if it's a directory, recursively search it
if (finder.IsDirectory()) //????(??)??.... { FolderSearch(DirectoyName); // ? ????? ?? ?? ??? ????? ??? ?? ??
} else //?????... { CString strFilePath = finder.GetFilePath(); CString strFileName = finder.GetFileName(); int n = strFileName.ReverseFind('.');
// CString strExt = strFileName; CString strExt = strFileName.Right(4) ; // strFileName = strFileName.Left(n); strExt.MakeUpper(); if(strExt == ".MP3" ) FileAdd(strFileName,strFilePath); }
} finder.Close(); PubSetItemCount_Text();}

vc에서 웹페지 가져오는 방법

void CSearchDlg::ConnectWeb(CString strURL, CString strPostData){ CString head = _T("Content-Type: application/x-www-form-urlencoded\r\n");
CComVariant vtPostData;
COleVariant vaHead(head);
TCHAR* postData = NULL; postData = new TCHAR[ strPostData.GetLength()+1 ]; _tcscpy( postData, strPostData.GetBuffer() );
int len = _tcslen(postData);
SAFEARRAY *pSafeArray = SafeArrayCreateVector(VT_UI1,0,len);
if(!pSafeArray) return ;
char *value = NULL;
if(SafeArrayAccessData(pSafeArray,(void **)&value) != S_OK) return ;
for(int i=0; i< len;i++)
{
value[i] = (char)postData[i];
}
if(SafeArrayUnaccessData(pSafeArray) != S_OK) return ;
V_VT(&vtPostData) = VT_ARRAY VT_UI1;
V_ARRAY(&vtPostData) = pSafeArray;
m_explorer.Navigate(strURL,NULL,NULL,&vtPostData,vaHead);
}

언어 설정

Setlanginfo(void)
LANGID langID =GetSystemDefaultLangID();
m_nLang=LANG_KOREA;
1.LangID ==0x0412 LangId==oxo812//한국어
2.LangID==0xo804//중국어 간체
3.LangID==ox0404,ox0804,ox0c04,ox1004//중국어 번체
4.LangID==0x0411/일본어

AfxGetApp함수

AfxGetApp():어프리케이션 클래스의 개체포인트

AfxGetMainWnd()메인프레임이 클래스의 객체 포인트

AfxGetInstanceHandle():응용프로그램의 인스턴트

AfxGetAppName()응용 프로그램의 이름을 리턴

2007年10月19日星期五

AfxExtractSubString分割字符串的函数

AfxExtractSubString(CString& rString, LPCTSTR lpszFullString,int iSubString, TCHAR chSep = '\n')
CString& rString --- 得到的字符串
LPCTSTR lpszFullString --- 原来要分割的字符串
int iSubString -- 需要分割的第几段?
TCHAR chSep = '\n' -- 按照什么字符来分割?

ㅇㅇ

ㅇㅇㅇㅇ