1. 프로그램 시작하는 부분에 #include <crtdbg.h> _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); 를 넣는다. 2. 메모리릭을 체크할 부분에 아래 코드를 넣는다. #include <crtdbg.h> #ifdef _DEBUG #define new new(_CLIENT_BLOCK, __FILE__, __LINE__) #endif 3. 출력창에 메모리릭이 난부분을 클릭한다. 이동됨 4. MFC사용시에는 제거한다. 충돌됨
void gotoxy(int x, int y)
{
COORD Pos = {x - 1, y - 1};
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Pos);
}
// enable SetWindowPos(m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); // disable SetWindowPos(m_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
SetWindowLong(m_hWnd, GWL_EXSTYLE, WS_EX_LAYERED); SetLayeredWindowAttributes(RGB(0,0,0), 120, LWA_ALPHA);
enum
{
HOTKEY_MAXIMIZE = 100,
HOTKEY_RESTORE = 101,
HOTKEY_MINIMIZE = 102
};
void CHotKey::RegistHotKey()
{
BOOL bRet = RegisterHotKey(NULL, HOTKEY_MAXIMIZE, MOD_WIN, VK_UP);
if ( FALSE == bRet )
{
::MessageBox(NULL, L"Can't regist hotkey", L"", MB_OK);
}
bRet = RegisterHotKey(NULL, HOTKEY_RESTORE, MOD_WIN, VK_DOWN);
if ( FALSE == bRet )
{
::MessageBox(NULL, L"Can't regist hotkey", L"", MB_OK);
}
bRet = RegisterHotKey(NULL, HOTKEY_MINIMIZE, MOD_WIN, VK_LEFT);
if ( FALSE == bRet )
{
::MessageBox(NULL, L"Can't regist hotkey", L"", MB_OK);
}
}
void CHotKey::UnregistHotKey()
{
BOOL bRet = ::UnregisterHotKey(NULL, HOTKEY_MAXIMIZE);
if ( FALSE == bRet )
{
::MessageBox(NULL, L"Can't unregist hotkey", L"", MB_OK);
}
bRet = ::UnregisterHotKey(NULL, HOTKEY_RESTORE);
if ( FALSE == bRet )
{
::MessageBox(NULL, L"Can't unregist hotkey", L"", MB_OK);
}
bRet = ::UnregisterHotKey(NULL, HOTKEY_MINIMIZE);
if ( FALSE == bRet )
{
::MessageBox(NULL, L"Can't unregist hotkey", L"", MB_OK);
}
}
void CHotKey::OnHotKey(WPARAM hotkey)
{
switch ( hotkey )
{
case HOTKEY_MAXIMIZE:
{
HWND hTopWindow = ::GetForegroundWindow();
if ( hTopWindow != NULL )
{
::ShowWindow(hTopWindow, SW_MAXIMIZE);
}
}
break;
case HOTKEY_RESTORE:
{
HWND hTopWindow = ::GetForegroundWindow();
if ( hTopWindow != NULL )
{
::ShowWindow(hTopWindow, SW_RESTORE);
}
}
break;
case HOTKEY_MINIMIZE:
{
HWND hTopWindow = ::GetForegroundWindow();
if ( hTopWindow != NULL )
{
::ShowWindow(hTopWindow, SW_MINIMIZE);
}
}
break;
}
}
int isDebug()
{
int iRet;
__asm
{
mov eax, dword ptr FS:[0x30]
mov ebx, 0
mov bl, byte ptr [eax+2]
mov eax, ebx
mov iRet, eax
}
return iRet;
}
SRV*\\localhost\d$\Symbol\OSSymbols*http://msdl.microsoft.com/download/symbols;SRV*\\localhost\d$\Symbol\ProductSymbols;C:\Windows\system32
ShellExecute(HWND_DESKTOP, "open", "http://www.wimy.com", NULL, NULL, SW_SHOWNOACTIVATE );
이 글은 조경민(bro@ssm.samsung.co.kr)님이 작성하신 글을 스크랩 해온 것입니다.
=====================================================
[포함된 팁]
1. 특정 ROW 포커스 주기
2. 특정 ROW로 가기
3. 헤더 컬럼수 얻어오기
4. 컬럼의 너비를 이쁘게 주기
5. 한줄 쭉 선택되게 하기, 그리드 라인 주기
6. 선택한 아이템(ROW)를 지우기
7. 두 아이템을 스왑 하기
8.기존에 선택되어있는 것을 해체하기
1. 특정 ROW 포커스 주기
---------------------------------------------------
리스트 컨트롤에서 어떤 특정 Row를 선택하게 하고 싶을때 아래처럼 선택 할 수 있습니다.
( 이때 선택뿐아니라 포커스도 가야 합니다. 포커스가 간다는 의미는 다음에 키다운을 하면 바로 부드럽게 다음 아이템을 가리키도록 하는 것입니다 )
ListView_SetItemState (pListCtrl->GetSafeHwnd(), // handle to listview
10, // index to listview item
LVIS_FOCUSED | LVIS_SELECTED, // item state
0x000F); // mask
2. 특정 ROW로 가기
---------------------------------------------------
만일 원하는 Row를 스크롤을 하던 어떻게 하든 화면에 보이게 하고 싶을때
pListCtrl->EnsureVisible(15, TRUE);
3. 헤더 컬럼수 얻어오기
---------------------------------------------------
헤더 컬럼의 갯수를 알고 싶을때
CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
int nColumnCount = pHeader->GetItemCount();
또는 pList->GetHeaderCtrl()을 통해서 얻어올수 도 있습니다.
4. 컬럼의 너비를 이쁘게 주기
---------------------------------------------------
공백없이 컬럼의 너비를 컬럼 라벨 너비에 맞게 정렬해줍니다.
부모 다이얼로그의 OnSize에서
void CAttrListDlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
if( IsWindow( z_AttrList.m_hWnd ))
{
z_AttrList.MoveWindow( 0, 0, cx, cy );
z_AttrList.SetColumnWidth(1 , LVSCW_AUTOSIZE_USEHEADER);
}
}
5. 한줄 쭉 선택되게 하기, 그리드 라인 주기
---------------------------------------------------
z_AttrList.SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);
6. 다중 선택한 아이템(ROW)를 지우기
---------------------------------------------------
CDWordArray m_anDragIndexes; // 선택한 아이템을 기억하는
배열
int CAttrList::fnRemoveItem()
{
m_anDragIndexes.RemoveAll();
POSITION pos = GetFirstSelectedItemPosition();
while (pos)
{
m_anDragIndexes.Add(GetNextSelectedItem(pos));
}
int nSize = m_anDragIndexes.GetSize();
int nRet = -1;
if( nSize )
nRet = m_anDragIndexes[0];
while( nSize-- )
DeleteItem( m_anDragIndexes[nSize] );
m_anDragIndexes.RemoveAll();
return nRet;
}
7. 두 아이템을 스왑 하기
---------------------------------------------------
void CAttrList::fnSwapItem( int nItem1, int nItem2 )
{
int hi = nItem2;
int lo = nItem1;
CStringArray rowText;
LV_ITEM lvitemlo, lvitemhi;
CHeaderCtrl* pHeaderCtrl = GetHeaderCtrl();
int nColCount =pHeaderCtrl->GetItemCount();
rowText.SetSize( nColCount );
int i;
for( i=0; i
rowText[i] = GetItemText(lo, i);
lvitemlo.mask = LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
lvitemlo.iItem = lo;
lvitemlo.iSubItem = 0;
lvitemlo.stateMask = LVIS_CUT | LVIS_DROPHILITED |
LVIS_FOCUSED | LVIS_SELECTED |
LVIS_OVERLAYMASK | LVIS_STATEIMAGEMASK;
lvitemhi = lvitemlo;
lvitemhi.iItem = hi;
GetItem( &lvitemlo );
GetItem( &lvitemhi );
for( i=0; i
SetItemText(lo, i, GetItemText(hi, i));
lvitemhi.iItem = lo;
SetItem( &lvitemhi );
for( i=0; i
SetItemText(hi, i, rowText[i]);
lvitemlo.iItem = hi;
SetItem( &lvitemlo );
}
8.기존에 선택되어있는 것을 해체하기
-----------------------------------
int nOldItem = GetSelectionMark();
if( nOldItem > 0 )
SetItemState( nOldItem , 0, LVIS_SELECTED);
정리
이상으로 몇가지 리스트 컨트롤을 사용함에 있어 간단한 팁을 알아보았습니다.
#include <ObjBase.h>
#include <WTypes.h>
#include <ExDisp.h>
IWebBrowser2* m_pWebBrowser;
if (FAILED(CoInitialize(NULL)))
return FALSE;
// Instantiate a browser
if (FAILED(CoCreateInstance(CLSID_InternetExplorer,NULL,
CLSCTX_LOCAL_SERVER, IID_IWebBrowser2,
(LPVOID*)&m_pWebBrowser)))
return FALSE;
// Capture Explorer HWND
if((g_hExplorer = FindWindow("IEFrame", "Microsoft Internet Explorer")) == NULL)
return FALSE;
//m_pWebBrowser->put_Visible(TRUE);
m_pWebBrowser->put_Width(200);
m_pWebBrowser->put_Height(200);
//m_pWebBrowser->Navigate2(_T("http://www.wimy.com"), 0, 0, 0, 0);
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
// Start the child process.
if( !CreateProcess( NULL, // No module name (use command line).
"BugReporter.exe", // Command line.
NULL, // Process handle not inheritable.
NULL, // Thread handle not inheritable.
FALSE, // Set handle inheritance to FALSE.
0, // No creation flags.
NULL, // Use parent's environment block.
NULL, // Use parent's starting directory.
&si, // Pointer to STARTUPINFO structure.
&pi ) // Pointer to PROCESS_INFORMATION structure.
)
{
//ErrorExit( "CreateProcess failed." );
}
char szGetFileName[FILENAME_MAX] = { 0 };
DWORD ret = GetModuleFileName(GetModuleHandle(NULL), szGetFileName, FILENAME_MAX);
if ( ret == 0 )
{
_ASSERTE(!"Can't get module folder");
}
char szDrive[_MAX_DRIVE] = { 0 };
char szDir[_MAX_DIR] = { 0 };
_splitpath(szGetFileName, szDrive, szDir, 0, 0);
m_strProgramFolder = szDrive;
m_strProgramFolder += szDir;
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
IWebBrowser2 * pWebBrowser;// = (IWebBrowser2*)(&m_explorer);
CComPtr<IUnknown> pWebBrowserUnk = m_explorer.GetControlUnknown();
// IWebBrowser2 Interface 얻기
HRESULT hr = pWebBrowserUnk->QueryInterface(IID_IWebBrowser2, (void**)&pWebBrowser);
if ( !SUCCEEDED(hr) ) AfxMessageBox("error : m_pWebBrowserUnk->QueryInterface");
//m_webBrowser.MoveWindow(0, 0, MAKER_SELECT_WIDTH, MAKER_SELECT_HEIGHT, true);
pWebBrowser->GoHome();
1.함수에서 CWnd 가 필요한데 HWND밖에 없을 때
CWnd* pWnd = CWnd::FromHandle(HWND);
2.HWND가 필요한데 CWnd 밖에 없을때
HWND hWnd = pWnd->m_hWnd;
안녕하세요. 매크로 없는 메비~랍니다. 저는 포기했지만 좀 엄한 기능을 활용할 수 있습니다. 컴파일 옵션에 보면 함수가 시작될때마다 특정 함수를 호출하게 하는 컴파일 옵션이 있습니다. 프로파일러등에서 쓰이기 위해서 넣는것이라는데 VS.NET 2003 에서의 컴파일 옵션은 /Gh /GH 두가지입니다. 함수가 불리고 리턴할때마다 한번씩 호출되어주는 것인데 이것을 이용하면 프로파일러를 만들 수 있습니다. 단지.. 함수 호출시마다 부하가 걸리는 문제가 있고 함수 포인터별로 잘 정리해서 써야하는 문제가 추가로 발생하겠죠. 아.. 질문의 답변을 빠트렸군요. Debugging API 란 녀석들을 쓰면 함수 이름을 알 수 있습니다. 써야 할 함수는 SymFromAddr() 류의 symbol lookup 하는 함수입니다. 관련 정보를 얻으시려면 Debugging Application 류의 책과 몇몇 디버거 관련 자료를 직접 읽어보시는 쪽이 가장 빠를텐데 일단 이 함수와 PDB를 함께 사용하면 쉽게 함수 포인터나 실행중의 IP(Instruction Pointer)에서 함수명을 알아낼 수 있습니다. p.s.VS 6.0에서 해볼때는 /GH 가 없더니 이번에 생겼군요. p.s.2.검색할때 "Calls hook function _penter" 내용으로 검색 해보시면 될듯~
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi) );
if ( !CreateProcess( NULL,
"Z:A.exe C:execconf",
NULL,
NULL,
FALSE,
0,
NULL,
NULL, &si, &pi) )
{
DWORD dwErrorCode = GetLastError();
cout << "Can't create process : " << dwErrorCode << endl;
return -1;
}
else
{
WaitForSingleObject(pi.hProcess, INFINITE);
if (!CloseHandle(pi.hProcess) ) cout << "Can't CloseHandle pi.process" << endl;
if (!CloseHandle(pi.hThread) ) cout << "Can't CloseHandle pi.thread" << endl;
}
m_listControl.SetExtendedStyle(LVS_EX_FULLROWSELECT);
void ZFindFile(const char *path, std::vector<std::string> & foundStorage, bool bFindRecursive = false)
{
HANDLE hSrch;
WIN32_FIND_DATA wfd;
//memset(&wfd, 0, sizeof(wfd));
char fname[MAX_PATH] = { 0 };
BOOL bResult=TRUE;
char drive[_MAX_DRIVE] = { 0 };
char dir[MAX_PATH] = { 0 };
char newpath[MAX_PATH] = { 0 };
hSrch=FindFirstFile(path,&wfd);
while (bResult)
{
if ( m_bStop == true ) return;
_splitpath(path,drive,dir,NULL,NULL);
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if (wfd.cFileName[0]!='.' && bFindRecursive == true)
{
wsprintf(newpath,"%s%s%s*.*",drive,dir,wfd.cFileName);
ZFindFile(newpath, foundStorage, bFindRecursive);
}
}
else
{
wsprintf(fname,"%s%s%s",drive,dir,wfd.cFileName);
foundStorage.push_back(fname);
}
bResult=FindNextFile(hSrch,&wfd);
}
FindClose(hSrch);
}
void DeleteRecursive(const std::string & strFolderName)
{
HANDLE hSrch;
WIN32_FIND_DATA wfd;
//memset(&wfd, 0, sizeof(wfd));
char fname[MAX_PATH] = { 0 };
BOOL bResult=TRUE;
char drive[_MAX_DRIVE] = { 0 };
char dir[MAX_PATH] = { 0 };
char newpath[MAX_PATH] = { 0 };
hSrch=FindFirstFile(strFolderName.c_str(),&wfd);
while (bResult)
{
_splitpath(strFolderName.c_str(),drive,dir,NULL,NULL);
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if (wfd.cFileName[0]!='.' )
{
wsprintf(newpath,"%s%s%s*.*",drive,dir,wfd.cFileName);
DeleteRecursive(newpath);
}
}
else
{
wsprintf(fname,"%s%s%s",drive,dir,wfd.cFileName);
DeleteFile(fname);
}
bResult=FindNextFile(hSrch,&wfd);
}
FindClose(hSrch);
}
void DeleteFolderRecursive(const std::string & strFolderName)
{
if ( strFolderName[strFolderName.size()-1] == '')
{
_ASSERTE(!"마지막 캐릭터가 'W'가 될 수 없습니다.");
return;
}
std::string strTemp = strFolderName;
strTemp += "*.*";
DeleteRecursive(strTemp);
RemoveDirectory(strFolderName.c_str());
}
BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam)
{
char sbufClass[100], sbufUrl[300];
int nLenForUrl = 0;
cout << "EnumChildProc Called" << endl;
GetClassName(hwnd, sbufClass, 100);
if( stricmp( sbufClass, "EDIT" ) == 0 ){
nLenForUrl = ::SendMessage( hwnd, WM_GETTEXTLENGTH, 0, 0 );
nLenForUrl = nLenForUrl + 1;
::SendMessage( hwnd, WM_GETTEXT, nLenForUrl, (LPARAM)sbufUrl );
//AfxMessageBox(sbufUrl, MB_OK, 0);
cout << sbufUrl << endl;
}
return TRUE;
}
void OnOk()
{
HWND hwnd;
WNDENUMPROC wndEnumProc = EnumChildProc;
char temp[200];
char result[200] = { 0 };
hwnd = ::FindWindow("Winamp v1.x", NULL);
if( hwnd != 0 )
{
int len = SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0);
SendMessage(hwnd, WM_GETTEXT, len + 1, (LPARAM)temp);
// . 을 찾는다.
for ( int i=0; i<len; i++)
{
if ( temp[i] == '.' ) break;
}
//strncpy(result, temp + i + 2, len - 12);
//cout << result << endl;
::EnumChildWindows( hwnd, wndEnumProc, 0L);
}
else
{
cout << "can't find" << endl;
}
}
#include "stdafx.h"
#include <windows.h>
#include "resource.h"
int CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance ,LPSTR lpszCmdParam,int nCmdShow)
{
DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, WndProc);
return 0;
}
int CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
switch(iMessage)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
{
switch ( wParam )
{
case IDOK:
PostQuitMessage(0);
break;
}
}
break;
case WM_PAINT:
hdc=BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return FALSE;
}
HINSTANCE hInst= GetModuleHandle(NULL);
Developer Studio가 생성하는 파일들에 대한 목록 파일 확장자 내용 APS 리소스 파일에 대한 바이너리 파일. App Studio에서 리소스 파일을 로딩하는데 사용된다.(로딩 속도 향상) BSC 소스 브라우저 정보 파일(Browser database file). 이 파일은 BSCMAKER.EXE를 실행할 때 SBR파일로부터 생성된다. CLW 클래스위저드 상태 파일. 클래스위저드를 사용하여 추가되는 메시지 핸들링 함수 등과 관련된 정보들이 포함된다. DSP 메이크 파일(MAK)과 동일한 목적의 파일로 VC++5.0에서 사용한다. DSW 워크스페이스 파일 . 워크스페이스내의 각 프로젝트에 대한 엔트리 정보를 포함 한 파일 PCH 프리컴파일 헤더 파일 (Precompiled header file). 이 파일은 컴파일 속도를 향상 시키며 컴파일 옵션/Yc, /Yu 또는 /YX를 사용할 때 생성된다. PDB 프로그램 정보 파일(Program database file). 이 바이너리 파일은 컴파일링, 링킹 과정을 통해 얻어지는 디버깅 정보를 포함한다. SBR 소스 브라우저 파일(Source browser file). 이 파일은 소스 파일에 대한 상세한 정보들이 포함된다. WSP Workspace information file(16비트 버전)은 통합 개발 환경이 종료될때의 상태 정보를 포함한다. VCP Workspace information file(VC++ 2.X버전 또는 이후버전)은 통합개발 환경이 종료될때의 상태 정보를 포함한다. EXP 익스포트 파일 (Export file). 익스포트되는 힘수와 데이터 정보를 포함한다. MAP 맵 파일(Map file). 프로그램의 엔트리 포인트, 심볼이름, 시작 주소, rlfdled 프로 그램에 링크된 정보를 포함한다. RES 리소스 파일(RC)이 컴파일된 바이너리 파일 HPJ 문맥김지형 도움말 파일(Context-sensitive help project file). AppWizard 단계 4 에서 [Context-sensitive help]를 체크하면 자동 생성된다. NCB Parser information file. 이 파일은 클래스뷰와 컴포넌트 갤러리를 지원하기 위한 정보를 포함한다. MDP Microsoft Developer Studio file. 이 파일은 VC++ 2.X 버전에서 사용한 VCP파일 을 대체한다. RCT 리소스 템플릿 파일 (Resource template file) OPT 워크스페이스 환경설정을 보유 PLG 빌드 로그 파일
switch (msg)
{
....
case WM_SYSCOMMAND:
if (wParam == SC_SCREENSAVE)
return 0;
DefWindowProc(hWnd, message, wParam, lParam);
....
}
//초기화 하실때 이 코드를 넣으면, 스크린세이버가 죽습니당.
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE,
FALSE,
0,
SPIF_SENDWININICHANGE);
//그리고, 종료할때는 다음과 같이..
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE,
TRUE,
0,
SPIF_SENDWININICHANGE);
HANDLE hMutex;
// Create a mutex with no initial owner.
hMutex = CreateMutex(
NULL, // no security attributes
TRUE, // initially not owned
"MyProgram"); // name of mutex
if (hMutex == NULL || GetLastError() == ERROR_ALREADY_EXISTS)
{
// Check for error.
// 이미 같은 프로그램이 떠 있다.
return 0;
}
// MainLoop
// .....
// .....
// Release Mutex
BOOL ret = ReleaseMutex(hMutex);
ret = CloseHandle(hMutex);