페이지

2010년 3월 7일 일요일

[두루에디트 제작기] Kill or Prevent Beep in Edit Control ,Editctrl 에디트 컨트롤 비프음 없애기

Subclass your Edit control,
and processing WM_CHAR message, return 1 to avoid default window routine;

e.g) sample of duruedit source

BOOL SubClassEditCtrl::OnChar(UINT nChar,UINT nRepCnt,UINT nFlags)
{
//if(m_nLastChar == 0)
// SetWindowText(m_hWnd,"");
//m_nLastChar = nChar;
if (nChar == VK_TAB nChar == VK_RETURN nChar == VK_ESCAPE)
{
//비프음을 없앤다
return 1;
}
return 0;//pass to default proc
}




또는 PreTranslateMessage에서 해당 다이얼로그나 컨트롤을 탑재한 윈도우가 떠 있는 경우(프레임과는 별도로),포커스를 받기원하고 비프음을 제거하려면 기본 로직을 타지않도록 return TRUE 하면 된다.

아래는 KFC 라이브러리로 개발중인 두루에디터의 실례이다.

여기서 KFCLib 의 경우의 PreTranslateMessage함수는 sdk로 따지자면 GetMessage 루프에서 검사해오는 루틴에 끼어있는것이다.

만일,MFC는 같은 이름의 함수부분에서 처리하고 SDK 라면 WinMain의 GetMessage,PeekMessage 부분에서 검사하면 마찬가지 효과이다.

BOOL DEMainWnd::PreTranslateMessage(MSG* pMsg)
{
//2010.0226 krkim 검색창 에디터에 copy/paste가 잘 안듣는 문제해결
//키보드 엑셀레이터를 못타도록 하여 편집창이 처리하지 않고 검색창 에디터가
//처리하도록 내버려 둔다.
if (::IsWindow(m_dlgFinder.GetSafeHwnd()) && IsDialogMessage(m_dlgFinder.GetSafeHwnd(),pMsg))
return TRUE;//FALSE TO Translate

if(m_wndFindBar.PreTranslateMessage(pMsg))//FindBar 콤보박스의 에디터에 키입력 메세지를 날리기 위해..
return TRUE;

//TRACELOG("hWnd = %X,nChar = %X bCtrl = %d m_wndFindBar.m_hEditBox = %X,hActiveEdit=%X\n",
// pMsg->hwnd,nChar,bControl,m_wndFindBar.m_hEditBox,hActiveEdit);
if (::IsWindow(m_wndFindBar.GetSafeHwnd()) && IsDialogMessage(m_wndFindBar.GetSafeHwnd(),pMsg))
return TRUE;

return KFCMDIFrame::PreTranslateMessage(pMsg);
}


예로,본인이 WTL + SDK + MFC 의 장점만을 따와 자작한 KFC 라이브러리는 ,실행속도와 파일크기는 MFC > WTL > SDK 순으로 느린 반면에, KFC 라이브러리는 WTL과 SDK의 거의 중간급에서의 퍼포먼스를 나타내고 속도는 빠른 반면 개발이난해한 SDK의 단점과 WTL 코드의 어지러움등을 모두 한방에 해결하기 위해 만든 C++클래스 계층구조 형태로 자체제작한 윈도우즈 플랫폼 개발 라이브러리이다.

현재 버전은 즉,
Window 클래스로는
KFCApp
KFCWnd - KFCDlg
- KFCFrame - KFCMDIFrame
- KFCMDIChild , KFCMDIWnd
- KFCToolbar
- KFCPropPage,KFCPropSheet
- KFCScrollBar
- KFCButton - KFCSkinButton
- KFCStatic
- KFCLabel
- KFCTabCtrl - KFCMDITabCtrl
- KFCToolTop
- KFCHotKeyCtrl

DC 관련 클래스로는,
KFCBitmap
KFCDC
KFCPaintDC
KFCWindowDC
등으로 구성되어져 있다.
현재 버전만으로 MDI,SDI,Dialog 기반등 모든 응용프로그램의 제작이 쉽게 가능하다.

예) 다이얼로그 호출법

KFCDlg dlg(IDD_MYDLG,m_hWnd);
int flag = dlg.DoModal();

형태로 SDK는 CreateDialog 등 복잡한 함수를 매번 나열해야 하지만,
쉽게 WTL이나 MFC의 것과 유사하게 코드가 간편하다.

나머지, 없는 클래스는, 그때그때 필요에 의해 작성하여 새롭게 추가할 것이다.
(몇년동안 그렇게 해왔고..실제 본인프로젝트에 강력하게 쓰고있고 강력함을 스스로 느낀다.^^)

KFC의 메세지 펌핑 루틴의 소스코드는 다음과 같다.
이라이브러리는 여유와 기회가 되면 오픈소스 차원에서 별도의 웹공간에 풀소스 공개할 생각이다..

int KFCApp::MessageLoop()
{
// The main message loop
int status;
MSG msg;
if(m_bInit == FALSE){
ExitInstance();
return -2;
}

//다이얼로그는 InitInstance()에서 DoModal() 호출할것!
//In Dialog Top Window,call DoModal() first in InitInstance().

//CHAR classname[80] = {0,};
//if(GetClassName(m_pMainWnd->m_hWnd,classname,sizeof(classname)) > 0)
// if(!stricmp(classname,"#32770"))
// return -2;
if(!m_pMainWnd){
throw KFCException("Warning! Please Indicate m_pMainWnd in InitInstance\n");
ExitInstance();
return -2;
}
BOOL bIdle = true;
for(;;)
{
while(bIdle && !::PeekMessage(&msg,NULL,0,0,PM_NOREMOVE))
{
if(!OnIdle())
bIdle = false;
}
status = GetMessage(&msg, 0, 0, 0);
if(status == -1)//error occured ,don't process
continue;
if(status == 0)//met WM_QUIT
break;
Run();
if(!PreTranslateMessage(&msg))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
bIdle = IsIdleMessage(&msg);
}
ExitInstance();
return msg.wParam;
}

댓글 3개: