천객만래 [千客萬來] (It has an interminable succession of visitors)

[VC] IE에 사용자 툴바를 설치후에 기본으로 보이게 하는 방법





IE에 새 툴바밴드를 설치하고 새 IE를 실행했을때 기본으로 툴바가 IE에 보여지도록 하는 방법에 대한 문서이다. 혹자는 이것이 왜 필요하냐고 물을수도 있는데, 한마디로 필요하다. 

왜냐하면 설치를 했다면 당연히 눈여보여서 동작하는 것이 사용자의 기대동작이기 때문이다. 만약 IE에서 툴바를 켜는 방법을 모르는 사용자가 있다면 어떨까? 설치를 한 의미가 없어진다. 사용을 촉진시키고, UI를 보여줌으로써 관심을 일으키는 것이 마케팅일것이다.

1 툴바 DLL의 기본 설정을 이용하는 방법 

이 방법을 알아낸다면 밑에 있는 방법은 다 없어도 된다. 이 방법은 웹 검색과 구글검색으로도 쉽게 알아내지 못했다. IE의 툴바 레이아웃은 
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Toolbar
There are 3 sub keys: Explorer, ShellBrowser, WebBrowser'
In each of these sub-keys is the entry for ITBarLayout 
For IE Toolbars: The WebBrowser Sub-key directly affects IE.
For Windows Explorer Toolbars: The Explorer Sub-key directly affects Explorer.
The ShellBrowser sub-key may affect IE as well. Its effect on IE and Windows Explorer is unknown at this time, so if the first option doesn't work, delete the ITBarLayout value here as well.
Choose the relavent sub-key and right click where it says ITBarLayout and select Delete. 
The deleted value will automatically be recreated for you.

이런식으로 저장이 된다. 문제는 ITBarLayout에 레이아웃 구조체가 저장되는데 이 키를 지우면 모든 레이아웃 정보가 사라지고 IE가 디폴트로 툴바 레이아웃을 생성하는데, 이때 특정 툴바는 기본으로 뜬다는 것이다. 설치하고 나서 기본으로 뜨고 사용자가 안 보이게 하면 그때 부터 안 보인다. 이런 설정은 어떻게 하는 것일까? 만들때 어떤 옵션을 주는것 같기도 하고. 만약 방법을 찾게 되면 이 페이지에서 가장 강조되는 블럭으로 말들어 놓겠다.

2 html을 이용하는 방법 

이 방법은 해당 툴바를 Object 태그로 HTML에 삽입하는 방법이다. 다시 말해서 해당 COM객체를 IE에서 실행하라고 알리는 것이다. 설치가 끝나고 나서 인스톨러가 설치가 완료되었다는 깜찍하고 작은 IE를 띄우는것은 애교로 봐 줄만하다. 그 IE가 띄우는 페이지에 저 Object에 툴바의 클래스 아이디를 넣는다는 얘기이다. HTML에서는 COM객체를 로드할 것이고, 그 객체는 툴바DLL이기 때문에 당연히 IE에 리바영역에 나타날 것이다. 

문제점이있다. 어떤 툴바는 로드되지 않는다. 내가 뜨기를 원하는 툴바에서는 안 뜨고 다른 툴바는 성공적으로 뜨는 바람에 바로 다른 방법을 강구하기 시작했는데, 자기가 배포하려는 툴바가 이 방법으로 잘 되는지 확인해 볼 필요가 있다. 

주의할 점은 winxp sp2에서는 기본 보안설정으로는 DLL이 로드되지 않는다는 점이다., IE의 보안레벨에 의존적이다.

3 IE 메뉴를 이용하는 방법 

새로운 IE를 실행하면서 그 IE의 IEFrame핸들을 얻을 수 있는데 그 윈도우 핸들에 WM_COMMAND를 보내는 방법이다. 이 경우, 예를들면 Ctrl+N과 같은 IE의 기본적인 값은 spy++로 확인해 보면 항상 같다는 점을 알 수 있다. 그래서 테스트 결과 WM_COMMAND로 wParam에 그 값을 넣어서 보내면 정확히 그 메뉴가 실행된다. 이 점을 응용하면 보기-툴바에서 우리 툴바의 메뉴아이템의 ID를 구하기만 하면 되는 것이다. 그 ID는 항상 동적이다. 설치된 툴바의 갯수나 설치된 순서에 따라 다르기 때문이다. 그래서 IE의 메인메뉴를 HMENU를 구하고 거기서 모든 메뉴 아이템을 얻어서 우리가 원하는 메뉴 캡션을 찾아내면 그 메뉴 아이템의 ID가 우리가 찾는 ID가 되는 것이다.

[치명적 문제점]
메인메뉴의 HMENU 값을 구할 수가 없다? 일단 GetMenu(HWND) 는 메뉴가 없다. 왜 그럴까? IE의 메인메뉴는 메뉴바라고 하는 툴바에 올라가 있고, 팝업메뉴로 나타나기 때문이다. HMENU만 알아낸다면 확실히 효율적이고 안정적인 좋은 방법이다.

4 IWebBrowser2를 이용하는 방법 




STDMETHODIMP CShowBarObj::SetSite(IUnknown *pUnkSite)

(

 if (NULL != pUnkSite)

 {

  IWebBrowser2 *pBrowser = NULL;

  // Ensure that our site is an browser window

  HRESULT hr = pUnkSite->QueryInterface(IID_IWebBrowser2, (void **) &pBrowser);

  if (SUCCEEDED(hr))

  {

   // Display the band object (the Search bar in this case)

   VARIANT vtBandGUID, vtShow;

   vtBandGUID.vt = VT_BSTR;

   vtBandGUID.bstrVal = SysAllocString(OLESTR("{30D02401-6A81-11D0-8274-00C04FD5AE38}"));

   vtShow.vt = VT_BOOL;

   vtShow.boolVal = true;

   VARIANT vret;

   pBrowser->ShowBrowserBar(&vtBandGUID, &vtShow, &vret);

   SysFreeString(vtBandGUID.bstrVal);

   pBrowser->Release();

  }

 }

 return S_OK;

}




이 코드인데 이 코드를 툴바(툴바는 문제가 있는데 툴바는 켜지 않으면 DLL을 로드하지 않기 때문이다.)나 BHO에 넣으면 잘 동작한다. 그러나 IE를 실행하고 그 실행한 IE의 IWebBrowser2의 ShowBrowserBar를 호출하면 절대로 동작하지 않는다. 그것이 문제이다. 일단 그 이유를 모르겠다. 한가지 생각나는 이유라고는 TopLevel의 IWebBrowser2가 아니기 때문이 아닐까 싶기도 한데, 사실상 그런 이유때문은 아닌것 같다. 

아래 코드는 Activex에서 탑 레베의 IWebBrowser2를 얻는 코드이다. 나중에 참조해 볼 것.





#include <SHLGUID.h>

#define COMRELEASE(ptr)

if (ptr != NULL) 

{

ptr->Release();

   ptr = NULL;

}

IWebBrowser2 *browser = NULL;

STDMETHODIMP SetClientSite(IOleClientSite *pClientSite) 

{

  HRESULT hr = S_OK;

   IServiceProvider *isp, *isp2 = NULL;

    if (!pClientSite)

{

 COMRELEASE(browser);


else

{

hr = pClientSite->QueryInterface(IID_IServiceProvider, reinterpret_cast<void **>(&isp));

if (FAILED(hr)) 

{

hr = S_OK;

goto cleanup;

}

hr = isp->QueryService(SID_STopLevelBrowser, IID_IServiceProvider, reinterpret_cast<void **>(&isp2));

if (FAILED(hr))

{

hr = S_OK;

goto cleanup;

}

hr = isp2->QueryService(SID_SWebBrowserApp, IID_IWebBrowser2, reinterpret_cast<void **>(&browser));

if (FAILED(hr)) 

{

hr = S_OK;

goto cleanup;

}

cleanup:

// Free resources.

COMRELEASE(isp);

COMRELEASE(isp2);

return hr;

}

}


5 BHO를 이용하는 방법 

이 방법이 그나마 안정적이고 좋은방법 같다. ShowBrowserBar를 BHO에서 동작하도록 하는 것이다. BHO의 SetSite에서 우리가 원하는 툴바를 보이게 만들고 DLL을 등록해제해서 (레지스트리 삭제) 다음 IE에서는 이 DLL을 다시 로드하지 않도록 하는 방법이다. 

bho등록
IE를 안 보이게 실행
로드된 bho에서 우리가 원하는 툴바를 보이게 함
IE를 종료함 WM_CLOSE를 보내거나 ->Quit를 호출함
bho등록해제
bho dll삭제

와 같은 순서로 동작한다.

6 레이아웃 레지스트리를 조작하는 방법

레지스트리는 바이네리 데이타이다. 상식적으로 생각했을때 그건 IE내부에서만 사용되는 어떤 구조체일 것이고, 그 내막은 파악하기는 소스가 없다면 리버스엔지니어링이라고 불리는 삽질을 하는 수 밖에 없는 법이다. 당행스럽게도 나에겐 win2k src가 있었는데 없었다면 감히 삽질하려고 시도조차 하지 않았을 것이다. 그런데 그런 시도를 이미 한 사람이 있었으니 내가 감탄하지 않을 수 없었다. 구조체는


typedef struct tagCOOLBARSAVE
{
  UINT cbVer;
   UINT uiMaxTBWidth;
    UINT uiMaxQLWidth;
#ifdef UNIX
    BITBOOL fUnUsed : 28; // unused
#endif
  BITBOOL fVertical : 1; // The bar is oriented vertically
   BITBOOL fNoText :1; // "NoText"
    BITBOOL fList : 1; 
// toolbar is TBSTYLE_LIST (text on right) + TBSTYLE_EX_MIXEDBUTTONS
BITBOOL fAutoHide : 1; // Auto hide toolbar in theater mode
    BITBOOL fStatusBar : 1; // Status bar in theater mode
BITBOOL fSaveInShellIntegrationMode : 1; 
// Did we save in shell integration mode?
UINT uiVisible; // "Visible bands"
UINT cyRebar;
BANDSAVE bsCBANDSMAX;
CLSID aclsidExternalBands[ MAXEXTERNALBANDS ]; // Check classid
CLSID clsidVerticalBar; //clsid of bar persisted within vertical band
CLSID clsidHorizontalBar;
} COOLBARSAVE, *LPCOOLBARSAVE;




이렇다. 소스 코드를 분석해 본 결과 상당히 복잡한 방법으로 bs 멤버와 aclsidExternalBands에 저장되는 순서가 어떤 함수로 관계지어지고 uiVisible에 교묘한 방법으로 계산한 bit를 OR시켜야 한다. 등등 상당히 복잡한 방법으로 저장이 되고 있다는 점이다. 내가 수십시간에 걸쳐 분석하고 완성한 소스가 있지만 그것조차 100% 완벽하다고 장담하지 못하겠다. 솔직히 MS얘네들 간단한 내용을 왜 이렇게 복잡하게 만들었는지 모르겠다. 그냥 최대 15개의 툴바를 지원하므로 15개의 툴바에 구조체를 할당하고 보임 안보임 BOOL 변수와, 스타일 변수, 위치변수 3개만 있으면 다 될것 같은데, 뭐가 그리 복잡하게 만드어 놨는지. 간단하고 읽기좋고 단순한 알고리즘으로 충분히 리팩토링이 필요한 소스가 아닌가 하는 개인적인 불만이 있다.

7 가장 확실한 방법 



#include <mshtml.h>
void CDeletmeDlg::OnButton1()
{
 CoInitialize(NULL);
 IWebBrowser2 *pIE;
 HRESULT hr =  CoCreateInstance(CLSID_InternetExplorer, NULL,
  CLSCTX_LOCAL_SERVER,
  IID_IWebBrowser2,(void**)&pIE);
 pIE->put_Visible(VARIANT_TRUE);
 VARIANT vtBandGUID;
 VARIANT vtShow;
 VARIANT vtRet;
 vtBandGUID.vt = VT_BSTR;
 vtBandGUID.bstrVal = ::SysAllocString( L"{5258771B-ACBE-4974-8ABC-AE4969A2A5CD}" );
 vtShow.vt = VT_BOOL; 
 vtShow.boolVal = VARIANT_TRUE; //** 주의 true가 아니라 VARIANT_TRUE이다.
 vtRet.vt = VT_INT;
 vtRet.intVal = 1;
 //**주의 vtRet는 리턴값이므로 반드시 읽어야 한다.
 //NULL을 넣으면 제대로 동작하지 않는다..
 hr = pIE->ShowBrowserBar(&vtBandGUID, &vtShow, &vtRet); 
 SysFreeString(vtBandGUID.bstrVal);
 //주소바가 보이도록 설정되 있으면
 VARIANT_BOOL b;
 pIE->get_AddressBar(&b);
 if(b == VARIANT_TRUE)
 {    
  HWND hWnd=0;
  pIE->get_HWND((long*)&hWnd);
  if(::IsWindow(hWnd))
  {
   //수동으로 안 보이게한다.
   //put_AddressBar는 현재창에서는 되지만 종료하고 닫으면 주소바가 다시 보이게 되어 있다.
   //따라서 사용자가 메뉴를 누른것처럼 동작하도록 한 다면 리바의 위치정보를 즉시 다시 기록하게 된다.
   ::PostMessage(hWnd, WM_COMMAND, 41477, 0);
  }
 }
 pIE->Release();
}



내가 미처 몰랐는데 이 방식이 있다. 주의라고 표시되지 않은 부분에서 내가 실수를 해서 안 되었던 것이고, 이제 하니 잘 된다. 툴바를 새 줄로 놓는다면 그건 DLL에서 GetHostInfo인가 하는 함수에서 _BREAK을 제거하면 된다.




Posted by SB패밀리




[VC] IE 서브클래싱(subclass)


WNDPROC g_pOldProc;

static LRESULT CALLBACK MyIEProc(HWND, UINT, WPARAM, LPARAM);

 

 

void CBand::SubClass(HWND hWnd)

{

     // 64bit 환경을 위해서 SetWindowLongPtr() 사용

    g_pOldProc = (WNDPROC) SetWindowLongPtr(hwndOfCallingComponent, GWLP_WNDPROC, (LONG_PTR)IEProc);

}

 

LRESULT CALLBACK CBand::MyIEProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 BOOL bRes = false;

 if (Message == WM_SIZE)
  bRes = g_pBand->SetPosition();
 if (Message == WM_ERASEBKGND)
  bRes  = false;

 if (bRes == false)
  return CallWindowProc (g_pOldProc, hwnd, message, wParam, lParam);

}

// 위치 체크 및 이동
BOOL CBand::SetPosition()
{
 RECT rc;

 ::GetClientRect(m_BandWnd, &rc);
 if (rc.top == 0)
 {
  // 작업내용
 }

 return false;
}

 

 

참고 :

http://0x68.com/shorts/subclass.asp

http://social.msdn.microsoft.com/Forums/en/vclanguage/thread/7cd4b8b5-1cd6-4661-9f29-e0569156cea4

http://www.cyworld.com/soinho/1291233

Posted by SB패밀리

[작업] IE + Chrome => 주소창+검색창 어플리케이션 목업 작성중


일주일에 3~4일의 작업기간중에 작업을 하느라 생각보다 늦기는 했지만..

처음에 크롬 확장프로그램을 만드는 것에서 최신버전에서의 보안강화로

사용자가 직접 확장프로그램을 설치해야만 작동가능하다는 것 때문에

크롬 확장프로그램은 다음을 기약하기로 했다. 나중에 기회가 된다면

다른 기능들과 함께 만들수도 있겠지만 사용자가 직접 설치해야만 한다는 것이

크리티컬한 제약사항이라 방법을 선회했다.


따라서, 번들 배포를 이용한 다운로드한 프로그램의 사용자 동의에 따라 설치가 되므로 

더 많은 배포를 할 수 있게 된다. 그리고 기존의 인터넷 익스플로러에서만 키워드를

추출하는 방식에서 벗어나 한국에서는 20%이상의 검색 점유율을 갖는 구글 크롬을

추가하여 키워드 추출율을 높였다는 것이 기존의 상품보다 장점이라고 할 수 있다.


즉, 정상적으로 크롬 확장프로그램으로서의 작동하는 주소창, 검색창 후킹이 아니라

윈도우즈 시스템 메시지를 이용한 후킹으로 크롬에서 오고가는 메시지 정보를 

들여다보고 주소창, 검색창 기능을 완성하고  엔딩팝업과 팝언더 기능을 적용하였다.

여기에 토스트 팝업(배너) 기능을 추가할까 한다.


키워드 추출은 IE + Chrome 

광고 노출은 팝언더 + 엔딩팝업(후팝업) + 토스트배너(팝업)


이렇게 구성된 어플리케이션을 완성하고 상품화 할까 한다.






Posted by SB패밀리

국내 브라우저별 점유율 : 아직 IE가 85% 이상의 점유율을 보여주고 있다.

Source: StatCounter Global Stats - Browser Market Share



Source: StatCounter Global Stats - Browser Version Market Share



Source: StatCounter Global Stats - Browser Market Share



Source: StatCounter Global Stats - Browser Version Market Share


2010년12월과 2012년12월




Posted by SB패밀리

인터넷 익스플로러에서 세션, 쿠키 공유하지 않기


IE 8의 경우는 session, cookie가 공유되는 현상이 있습니다.


이를 공유하지 않기 위해서는 아래와 같은 방법을 사용하면 됩니다.


레지스트리 설정

HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main

SessionMering=0 (DWORD:32)

FrameMerging=0 (DWORD:32)


그 다음으로는 


C:\Program Files\Internet Explorer\iexplore.exe" -nomerge


위와 같은 파라메터 옵션을 추가합니다.






[출처] IE 8 쿠키 레셰어링|작성자 푸하하


Posted by SB패밀리

[개발/IE] 인터넷 익스플로러 새 탭 페이지 설정하는 방법

새 탭 페이지에서 사용되는 값

0= 빈페이지 . 
1=사용자의 첫 홈페이지. 
2=새 탭페이지  (about:Tabs 작동)

[IE8, IE9]
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\TabbedBrowsing
NewTabPageShow=2 

* IE9에서 동적으로 변경됨

[IE7] 기본 적으로 탭 설정 정보가 없음. 만들어서 값을 넣어야 함
 
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\TabbedBrowsing
ShowTabsWelcome=2 값으로 설정해야함

Posted by SB패밀리

[개인] 인터넷 익스플로러의 즐기찾기 및 사이드바의 위치


인터넷 익스플로러의 즐겨찾기 위치는 왜 왼쪽에만 있을까?

오른쪽이나 하단에 있으면 안되는 걸까?

선택가능한 UX가 되면 좋겠다.

오른쪽에 있으니. 개인적으로는 불편하다.




Posted by SB패밀리

[개발/IE] BHO(Browser Helper Object)란?

BHO(Browser Helper Object)란?

인터넷 탐색기를 사용하다보면 BHO(Browser Helper Object)가 문제를 발생하는 경우가 종종있다. 
아울러 넷트웍 속도의 저하의 주 원인중 하나도 사용자가 무분별하게 설치한 BHO때문에 발생하며, 
악성 스크립트의 전파 경로중 하나도 BHO인 경우가 많다.

따라서 필자는 BHO와 도구 막대를 관리할 수 있는 유용한 유틸리티라는 글을 통해 BHO를 관리할 수 있는 ToolbarCop이라는 프로그램을 소개했다.


그러면 BHO는 무엇일까?

Browser Helper Object라는 용어에서 알 수 있듯이 
BHO는 근본적으로 브로우저에서 지원하지 못하는 기능을 지원하기위해 플러그인 형태로 IE에 추가되는 DLL 모듈을 말한다. 
DLL 형태로 제공되며, IE를 실행하면 함께 실행되기 때문에 사용자는 그 실행 여부를 알 수 없고, 
따라서 현재는 상당히 많은 악성 프로그램이 이 BHO를 이용해서 실행 코드를 심고 있다.

PDF 파일을 웹 브로우저상에서 읽을 수 있는 아도브사의 Acrobat 플러그인도 이러한 BHO 중 하나이며, 
웹 개발자의 필수품, IE Developer Toolbar이라는 글에서 소개한 IE Developer Toolbar도 BHO이다. 
또한 e2give의 ieBHOs.dll 제거하기라는 글에서 알 수 있듯이 악성 프로그램 역시 BHO 형태로 배포되는 경우가 많다.

따라서 BHO는 ToolbarCop이나 Autoruns과 같은 프로그램을 이용해서 주기적으로 관리하는 습관을 들이는 것이 좋다


Posted by SB패밀리

[개발/MFC] IE 새창 띄우기
인터넷 익스플로러에서 새 창 띄우는 방법을 알아보자.

 if(m_spPopUpWeb == NULL)
  m_spPopUpWeb.CoCreateInstance(CLSID_InternetExplorer);

 if(m_spPopUpWeb)
 {
  USES_CONVERSION;
  VARIANT vtEmpty;
  VariantInit(&vtEmpty);

  CComBSTR bstrURL = lpszURL;

  m_spPopUpWeb->Navigate(bstrURL, &vtEmpty, &vtEmpty, &vtEmpty, &vtEmpty);
  //m_spPopUpWeb->put_MenuBar(VARIANT_FALSE);
  //m_spPopUpWeb->put_ToolBar(VARIANT_FALSE);
  //m_spPopUpWeb->put_AddressBar(VARIANT_FALSE);
  //m_spPopUpWeb->put_StatusBar(VARIANT_FALSE);
  //m_spPopUpWeb->put_Resizable(VARIANT_FALSE);
  //m_spPopUpWeb->put_Width(nWidth);
  //m_spPopUpWeb->put_Height(nHeight);
  m_spPopUpWeb->put_Visible(VARIANT_TRUE);
  //m_spPopUpWeb.Release();

 }

Posted by SB패밀리


BHO(Browser Helper Object)란?

인터넷 탐색기를 사용하다보면 BHO(Browser Helper Object)가 문제를 발생하는 경우가 종종있다.
아울러 넷트웍 속도의 저하의 주 원인중 하나도 사용자가 무분별하게 설치한 BHO때문에 발생하며,
악성 스크립트의 전파 경로중 하나도 BHO인 경우가 많다.

따라서 필자는 BHO와 도구 막대를 관리할 수 있는 유용한 유틸리티라는 글을 통해 BHO를 관리할 수 있는 ToolbarCop이라는 프로그램을 소개했다.


그러면 BHO는 무엇일까?

Browser Helper Object라는 용어에서 알 수 있듯이
BHO는 근본적으로 브로우저에서 지원하지 못하는 기능을 지원하기위해 플러그인 형태로 IE에 추가되는 DLL 모듈을 말한다.
DLL 형태로 제공되며, IE를 실행하면 함께 실행되기 때문에 사용자는 그 실행 여부를 알 수 없고,
따라서 현재는 상당히 많은 악성 프로그램이 이 BHO를 이용해서 실행 코드를 심고 있다.

PDF 파일을 웹 브로우저상에서 읽을 수 있는 아도브사의 Acrobat 플러그인도 이러한 BHO 중 하나이며,
웹 개발자의 필수품, IE Developer Toolbar이라는 글에서 소개한 IE Developer Toolbar도 BHO이다.
또한 e2give의 ieBHOs.dll 제거하기라는 글에서 알 수 있듯이 악성 프로그램 역시 BHO 형태로 배포되는 경우가 많다.

따라서 BHO는 ToolbarCop이나 Autoruns과 같은 프로그램을 이용해서 주기적으로 관리하는 습관을 들이는 것이 좋다.

 

Posted by SB패밀리
TAG BHO, IE, 개발

[VC] IE 서브클래싱(subclass)


WNDPROC g_pOldProc;

static LRESULT CALLBACK MyIEProc(HWND, UINT, WPARAM, LPARAM);

 

void CBand::SubClass(HWND hWnd)
{
     // 64bit 환경을 위해서 SetWindowLongPtr() 사용

    g_pOldProc = (WNDPROC) SetWindowLongPtr(hwndOfCallingComponent, GWLP_WNDPROC, (LONG_PTR)IEProc);
}

LRESULT CALLBACK CBand::MyIEProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 BOOL bRes = false;

 if (Message == WM_SIZE)
  bRes = g_pBand->SetPosition();
 if (Message == WM_ERASEBKGND)
  bRes  = false;

 if (bRes == false)
  return CallWindowProc (g_pOldProc, hwnd, message, wParam, lParam);

}

// 위치 체크 및 이동
BOOL CBand::SetPosition()
{
 RECT rc;

 ::GetClientRect(m_BandWnd, &rc);
 if (rc.top == 0)
 {
  // 작업내용
 }

 return false;
}

 

참고 :

http://0x68.com/shorts/subclass.asp
http://social.msdn.microsoft.com/Forums/en/vclanguage/thread/7cd4b8b5-1cd6-4661-9f29-e0569156cea4
http://www.cyworld.com/soinho/1291233

Posted by SB패밀리

Toolbar Button Style Guide

This guide will help you design icons for toolbar buttons that you add to the Windows Internet Explorer user interface.

Sizes

The Internet Explorer toolbar requires two sizes for all toolbar icons: 20x20 pixel and 16x16 pixel. The following table shows the difference between the two icons.

Dimensions (in pixels) Example icon
20x20 20x20 16 color
16x16 16x16 16 color

The 20x20 pixel icon is used with the default Internet Explorer toolbar. The 16x16 pixel icon is used when Internet Explorer is in full-screen mode.

Colors

Internet Explorer uses two states for all toolbar buttons: the active state and the default state.

When the user's mouse is over a toolbar button, it is in the active state. At other times, the toolbar button is in the default state.

In the active state, Internet Explorer uses the appropriate color icon for the toolbar button. In the default state, Internet Explorer uses the appropriate grayscale icon. The following table shows the types of icons used for the different states.

State Example icon
Active 20x20 256 color
Default 20x20 256 shade

In addition to the color differences, Internet Explorer uses two color depths: 256-color/shade icons and 16-color/shade icons. The 256-color/shade icons should be designed using the Windows; halftone palette, while the 16-color/shade icons should use the Windows 16 palette. The following table shows the different color depths used.

Depth Example icon
16-color 20x20 16 color
256-color 20x20 256 color
16-shade 20x20 16 shade
256-shade 20x20 256 shade

Design Tips

There are several things to keep in mind when designing toolbar buttons that are going to be integrated with the Internet Explorer user interface. In general, you will want to:

  • Use the same hues and saturation of colors as in the default toolbar icons to keep a consistent and integrated appearance.
  • Make sure the visual transition between your default and active images is smooth.

For 16-color/shade icons, you will want to:

  • Use the Windows 16-color palette.
  • Add a black border around the icon, except when it affects the readability of the image (like with arrows or "X" icons).
  • Keep a fairly flat appearance (little or no dimensioning or shading).

For 256-color/shade icons, you will want to:

  • Use the Windows halftone palette.
  • Use icon-style borders with gray or color as top and left borders and black as the bottom and right borders.
  • Make them more dimensional, using a light source from the upper-left corner and shading where appropriate.

Placing Icons

Toolbar icons need to be placed in two .ico files. The first .ico file should contain three color icons for your button. They are:

  • 16x16 16-color icon (Required)
  • 20x20 16-color icon (Optional)
  • 20x20 256-color icon (Required)

The second .ico file should contain three grayscale icons. The grayscale icons needed are:

  • 16x16 16-shade (Required)
  • 20x20 16-shade (Optional)
  • 20x20 256-shade (Required)

Currently, the 20x20 16-color/shade icons are not being used, so including them in the .ico files is optional. The 16x16 16-color/shade icons are used in full-screen mode, while the 20x20 256-color/shade icons are used in normal mode.

You can use a drawing or paint program to create the appropriate images for each of the icons. To create the .ico files, you can use a tool like Microsoft Visual Studio.

Related Topics

The following are links to topics related to toolbar buttons.

Overview

Tutorial

출처 : http://msdn.microsoft.com/en-us/library/aa753621(v=VS.85).aspx

Posted by SB패밀리

 ; Activex 사용안함 처리 (IE '추가기능 관리' 에 확인가능)
 HKCU "Software\Microsoft\Windows\CurrentVersion\Ext\Settings\$CAB_GUID_0"

            Flags = 1  (REG_DWORD)
            Version = *  (REG_SZ)


 

 ; Activex 사용안함 제거
 DeleteRegKey HKCU "Software\Microsoft\Windows\CurrentVersion\Ext\Settings\$CAB_GUID_0"


 

 ; Kill bit 처리 (IE '추가기능 관리' 에서 해당 activex항목표시 자체가 사라짐. 해당 activex 구동안됨)


 HKLM "SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\$CAB_GUID_0"

          Compatibility Flags = 0x400 (REG_DWORD)

 

 ; Kill bit 제거
 DeleteRegKey HKLM "SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\$CAB_GUID_0"
 

 

 ; 레지스트리 등록 (실행 골드바 나오지 않도록)
 WriteRegDWORD HKCU "Software\Microsoft\Windows\CurrentVersion\Ext\Stats\$CAB_GUID_0\iexplore" "Flags" 4

 

 


Killbit 관련 정보


http://support.microsoft.com/kb/240797/ko

Posted by SB패밀리



출처 :  http://blog.naver.com/xinfra/80007923632

1. 툴밴드(Tool Band)란?
-----------------------------

이건 IE의 확장자입니다. IE의 상단에 CoolBar가 보이시죠? 그 안에 여러개의 ToolBar들이 들어 있는데, 거기다가 내가 만든 툴바를 집어 넣고 싶을때 쓰는겁니다.
보기/도구모음 메뉴에서 (또는 쿨바 위에서 오른클릭) 툴바들을 보이고 감추고 할 수 있죠.

이 놈과 유사품으로 Explorer Bar와 Desk Band가 있습니다.
Explorer Bar는 보기/탐색창 메뉴에서 선택되는 항목으로 브라우저의 왼쪽에 세로로 튀어 나옵니다.
Desk Band는 IE 확장자가 아니라 윈도우즈 확장자라고 해야 하나요? 모니터 젤 아래쪽에 작업표시줄이 있죠? (시작버튼이 있는 줄) 거기에 들어가는 밴드입니다.
이 둘은 오늘 강좌의 주메뉴인 ToolBand와 거의 똑같습니다. MSDN에도 세 놈을 같이 취급하고 있구요.

아마도 오늘은 상당히 복잡하고도 긴 글이 될것 같은데요. 예제로 만들어 볼 밴드는 델마당 검색밴드입니다.
이름을 델밴드라고 붙였는데요(대일밴드가 아님) 델마당 홈페이지 왼쪽 상단에 게시판 검색 폼이 있죠? 그 놈과 같은 기능을 하는데, 이건 밴드로 붙는 겁니다.


2. 들어가기 전에...
-----------------------------

오늘은 확장자들을 좀 더 고급스럽게 등록하는 방법을 한 번 살펴보도록 하겠습니다.
지금까지는 COM 등록 따로(델파이메뉴에서), 확장자 등록 따로(REG 화일로) 했었는데요, 이제는 한 방에 모조리 등록해 버리는 방법을 알아보도록 하지요.
처음에 마법사로 프로그램 시작 준비를 하면, 맨 아래쪽에

initialization
 TComObjectFactory.Create(ComServer, TDelSearch, Class_DelSearch,
   'DelSearch', '', ciMultiInstance, tmApartment);
end.

이런게 하나 생겼죠? 도데체 이게 뭐하는 놈인지 궁금하지 않으셨나요? 컴포넌트 공장?
이 TComObjectFactory 라는 클래스는 프로그램 동작시에 필요한 게 아닙니다. 바로 설치/제거 시에 사용되는 건데요. 델파이메뉴에서 Register ActiveX Server 또는 Unregister ActiveX Server를 누르면 바로 이 공장이 가동되는 겁니다.
혹은 도스창에서 Regsvr32.exe 로 설치할 경우도 마찬가지 입니다. (델파이도 아마 이걸 이용할지도..)
TComObjectFactory 는 기본적인 기능 즉, COM 서버로 등록하고 제거하고 하는 기능 밖에 없기때문에 다른 부분의 레지스트리도 같이 조작하기 위해서는 공장을 따로 만들어야합니다. 간단히 TComObjectFactory 를 상속받아 만들면 되는데요, 오늘 예제 프로그램에 들어가 있는 공장은 이렇습니다.

type
 ComFacProc = procedure;

 TComFac = class (TComObjectFactory)
 private
   FInstallProc, FUnInstallProc : ComFacProc;
 public
   constructor Create(ComServer: TComServerObject; ComClass: TComClass;
     const ClassID: TGUID; const ClassName, Description: string;
     const InstallProc, UnInstallProc : ComFacProc;
     Instancing: TClassInstancing; ThreadingModel: TThreadingModel = tmSingle);
   procedure UpdateRegistry(Register: Boolean); override;
 end;

복잡한것 같지만 실은 아주 단순합니다.
모든 기능을 그대로 상속 받으면서 설치시 실행될 함수, 제거시 실행될 함수를 각각 추가해 준것 뿐입니다.
이 예제에서는

procedure InstallProc;
begin
 REG_SetString(HKEY_CLASSES_ROOT, 'CLSID\' + GUIDToString(Class_DelSearch), '', BandCaption);
 REG_SetString(HKEY_CLASSES_ROOT, 'CLSID\' + GUIDToString(Class_DelSearch) + '\Implemented Categories\' + CATID_CommBand, '', '');
 REG_SetString(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Internet Explorer\Toolbar', GUIDToString(Class_DelSearch), '');
end;

procedure UnInstallProc;
begin
 REG_Delete(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Internet Explorer\Toolbar', GUIDToString(Class_DelSearch));
end;

initialization
 TComFac.Create(ComServer, TDelSearch,
                Class_DelSearch, 'DelSearch', '',
                InstallProc, UnInstallProc,           // 이 라인만 원래꺼와 다르죠.
                ciMultiInstance, tmApartment);
end.

이렇게 하면 원래의 COM 설치/제거 기능은 알아서 하고 저 덧붙인 함수들을 같이 수행하는 겁니다.
그런 이유로 오늘 부터는 REG 화일이 따라가지 않을 것입니다.
REG_xxx 함수들은 ComFac 유닛에 같이 포함되어 있습니다.


3. 레지스트리에 등록
-----------------------------

원래는 이게 뒤쪽에 나와야 하는데, 위에 공장 설명부분에 레지스트리 부분이 나왔기때문에 그냥 한꺼번에 해버릴려구요.

const
 CATID_DeskBand = '{00021492-0000-0000-C000-000000000046}';  // 태스크바 밴드 (DeskBand)
 CATID_InfoBand = '{00021493-0000-0000-C000-000000000046}';  // 탐색창        (ExplorerBar)
 CATID_CommBand = '{00021494-0000-0000-C000-000000000046}';  // 툴바 밴드     (ToolBand)

툴 밴드는 위의 공장처럼
 HKEY_CLASSES_ROOT\CLSID\{Your Band Object's CLSID GUID}\Implemented Categories\{00021494-0000-0000-C000-000000000046} (Key)
 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Toolbar\{Your Band Object's CLSID GUID} = '' (Value)
이렇구요.

탐색창은
 HKEY_CLASSES_ROOT\CLSID\{Your Band Object's CLSID GUID}\Implemented Categories\{00021493-0000-0000-C000-000000000046} (Key)
 HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Explorer Bars\{Your Band Object's CLSID GUID} (Key)
 HKEY_CLASSES_ROOT\CLSID\{Your Band Object's CLSID GUID}\Instance\CLSID = '{4D5C8C2A-D075-11D0-B416-00C04FB90376}' (Value)
 HKEY_CLASSES_ROOT\CLSID\{Your Band Object's CLSID GUID}\Instance\InitPropertyBag\Url = '탐색창의 컨텐츠가 있는 페이지의 URL' (Value)
을 각각 집어 넣습니다.

데스크밴드는 어떻게 등록하는지 모르겠군요. (--;) MSDN 설명서에는 이 부분이 없어요.
아시는 분은 꼬리를 달아주시길 바래요.

실제 MSDN예제들을 보면 저렇게 무식하게 레지스트리를 직접 건드리는게 아니라 준비된 인터페이스들 및 함수들을 이용해서 등록합니다.
이번 강좌에서 그걸 흉내 한번 내볼려다가 기능은 같은데 쓸데없이 복잡해지기만 할것 같아 그만 뒀습니다.
첨부파일에는 ComCat 이라는 유닛으로 포함은 되어 있지만 예제에서 사용은 하지 않습니다. 참고만 하세요.


4. 시작하자.
-----------------------------

지금까지와 같은 방법으로 새 프로젝트를 열고 COM공장부터 뜯어 고칩니다. 물론 그냥 두고 REG를 따로 세팅하는 방식으로 하셔도 상관은 없습니다.
그리고는 그대로 두고 File/"New Form" 메뉴를 누릅니다. 그렇습니다. 여태까지는 폼이 없는 확장자들이었지만 이건 폼이 필요합니다. 밴드를 넣으려면 밴드를 그려야죠.

ToolBand의 경우 ..

1. 폼에 CoolBar를 집어 넣는다.
2. CoolBar에 ToolBar를 집어 넣는다.
3. ToolBar에 놓고싶은 컨트롤들을 가져다 놓는다. (고수들은 ToolBar없이 CoolBar위에 바로 컨트롤을 올리기도 한다.)
4. 모양을 다듬는다. (폼의 BorderStyle는 bsNone로 하자)
  크기를 알맞게 조정하고 (AutoSize를 이용하면 편리하다) 폼의 Visible이 True로 되어있는지 확인도 하자. (누구처럼 그림 안나온다고 혼자 열받지 말자)

DeskBand, ExplorerBar의 경우는 해보질 않아 꼭 집어 말씀드리지는 못하겠구요. DeskBand는 뭐 ToolBand랑 똑 같을것 같구, ExplorerBar는 패널이나 아무컨트롤을 가져다 놓고 align을 alClient로 주면 되지 않을까 싶습니다.

자 이제 폼을 만들었으니, 메인유닛으로 돌아와서 그 폼의 유닛을 uses 절에 추가합니다.
추가하는 김에 ComObj, ShlObj, Shdocvw 등 필요한 유닛들도 모두 포함시킵니다.

이 세 개의 확장자들은 똑같이 IObjectWithSite, IPersistStream, IDeskBand 인터페이스를 구현합니다.
여기에 추가해서 "입력을 요구하는 컨트롤"이 폼에 존재할 경우에는 IInputObject 를 추가로 구현해야하고, 메뉴 항목에도 포함시키고 싶다면 IContextMenu를 또 추가해야합니다.
오늘 예제로 사용되는 놈은 이렇습니다.

 TDelSearch = class(TComObject, IObjectWithSite, IPersistStream, IDeskBand, IInputObject)
 private
   Band : TFormBand;                    // 앞에서 만든 폼이 Create 될 자리
   WinHandle : HWND;                    // IE CoolBar의 핸들을 보관할 자리
   InputObject : IInputObjectSite;      // 입력받는 부분이 있을경우 처리해야할 인터페이스
   HasFocus : Boolean;                  // 지금 내가 포커스를 가지고 있는지 아닌지?
   WebBrowser : IWebBrowser2;           // 웹브라우저

 protected
 {IObjectWithSite}
   function SetSite(const pUnkSite: IUnknown ):HResult; stdcall;
   function GetSite(const riid: TIID; out site: IUnknown):HResult; stdcall;

 {IPersist}
   function GetClassID(out classID: TCLSID): HResult; stdcall;
 {IPersistStream}
   function IsDirty: HResult; stdcall;
   function Load(const stm: IStream): HResult; stdcall;
   function Save(const stm: IStream; fClearDirty: BOOL): HResult; stdcall;
   function GetSizeMax(out cbSize: Largeint): HResult; stdcall;

 {IOleWindow}
   function GetWindow(out wnd: HWnd): HResult; stdcall;
   function ContextSensitiveHelp(fEnterMode: BOOL): HResult; stdcall;
 {IDockingWindow}
   function ShowDW(fShow: BOOL): HResult; stdcall;
   function CloseDW(dwReserved: DWORD): HResult; stdcall;
   function ResizeBorderDW(var prcBorder: TRect; punkToolbarSite: IUnknown; fReserved: BOOL): HResult; stdcall;
 {IDeskBand}
   function GetBandInfo(dwBandID, dwViewMode: DWORD; var pdbi: TDeskBandInfo): HResult; stdcall;

 {IInputObject}
   function UIActivateIO(fActivate: BOOL; var lpMsg: TMsg): HResult; stdcall;
   function HasFocusIO: HResult; stdcall;
   function TranslateAcceleratorIO(var lpMsg: TMsg): HResult; stdcall;
 end;

정말 만들어야할 함수들이 무지하게 많지요.
이걸 조목 조목 다 설명하려니 앞이 다 캄캄합니다요.
그래서 대충대충(^^;) 넘어가도록 하겠습니다.

먼저 쓸데없는 놈들부터 뽑아서 버리고 지나가죠.
입력받는 컨트롤이 있을경우 IInputObject를 반드시(굵은글씨) 구현하라고 되어 있길래 집어 넣었는데, 디버깅 결과 IE가 전혀 호출을 하지 않습니다. 왜 만들라고 했는지 모르겠군요 T.T
그래도 예제에는 원래 예제(Visual C용)를 그대로 델파이로 옮겨 놓았습니다.

IPersistStream도 이 예제에서는 써먹지 않습니다. MSDN이 말하길 ExplorerBar의 경우 데이터를 스트림으로 받아내거나 집어넣을때 써먹을수 있다고 합니다.
써먹든 말든 무조건 디폴트 리턴값을 돌려주면 되겠습니다.

그럼 이제는 핵심부를 살펴보도록 하죠.

SetSite란 놈은 초기화/마무리 부분이라고 생각하시면 되겠습니다.
초기화시에는 pUnkSite에 값이 담겨오고 마무리 부분에서는 nil이 넘어 옵니다.
---------------------------------------------------------------------------------------------
function TDelSearch.SetSite(const pUnkSite: IUnknown ):HResult; stdcall;
const
 IID_IOleWindow : TGUID = '{00000114-0000-0000-C000-000000000046}';  // 델파이는 이런 기본적인 것도 const로 만들어 놓질 않았다.
 IID_IInputObjectSite : TGUID = SID_IInputObjectSite;
var
 OW: IOleWindow;
begin
 if Assigned(InputObject) then begin         // 이게 할당 되어 있다면 마무리 호출이겟죠?
//     InputObject._Release;                
    InputObject := nil;
    end;

 Result := E_FAIL;
 WinHandle := 0;
 if Assigned(pUnkSite) then                  // IE CoolBar의 핸들을 얻어오기 위한 작업
 if SUCCEEDED(pUnkSite.QueryInterface(IID_IOleWindow, OW)) then begin
    OW.GetWindow(WinHandle);
//     OW._Release;
    end;

 if WinHandle<>0                             // 쿨바가 없거나 마무리 호출이면 WinHandle=0
    then Result := S_OK
    else Exit;

 WebBrowser := nil;
                                             // 이건 InputObject 인터페이스를 얻어오는 부분..
 if FAILED(pUnkSite.QueryInterface(IID_IInputObjectSite, InputObject)) then begin
    Result := E_FAIL;
    Exit;
    end;
                                             // 이건 웹브라우저의 인터페이스를 얻어 오는 부분
 if FAILED(((pUnkSite as IOleCommandTarget) as IServiceProvider).QueryService(IWebbrowserApp, IWebbrowser2, WebBrowser))
    then WebBrowser := nil;
                                             
 if not Assigned(Band) then begin            // 폼을 생성시키자. 단, CreateParented 로 생성할 것. Parent는 IE의 CoolBar.
    Band := TFormBand.CreateParented(WinHandle, WebBrowser);
    end;
 if not Assigned(Band) then Result := E_FAIL;
end;
---------------------------------------------------------------------------------------------
위에 보시면 _Release 부분이 모두 리마크가 되어 있죠? 원래는 다 _Release해 줘야하는데 델파이는 지가 알아서 한다고 프로그램에서 호출하지 말라고 합니다. 얼마나 잘 알아서 하는지 두고 보자구요. 실제로 _Release를 시키면 당장은 문제가 없는데, 프로그램 종료부분에서 문제가 발생합니다. 제가 이것땜에 엄청 고생을 했죠.

function TDelSearch.GetSite(const riid: TIID; out site: IUnknown):HResult; stdcall;
단지 QueryInterface의 역할을 하도록 만들라고 합니다. 위에서 받아낸 InputObject가 쓰이는 유일한 곳.
소스는 생략합니다.

function TDelSearch.GetWindow(out wnd: HWnd): HResult; stdcall;
내가 만든 폼의 핸들을 요청하는 통로입니다.
폼이 아직 안만들어 졌으면 Create하고, 핸들을 wnd에 넘겨주면 됩니다. 역시 소스 생략.

function TDelSearch.ShowDW(fShow: BOOL): HResult; stdcall;
내 밴드를 숨겨라/보여라 하는 명령이 전달되는 통로입니다.
True가 들어오면 보여주고, False가 들어오면 감추면 됩니다. 죽어도 감추기 싫다면 그냥 뻐팅겨도 됩니다.

function TDelSearch.CloseDW(dwReserved: DWORD): HResult; stdcall;
내 밴드를 뽀개라는 명령이 전달되는 통로입니다.
조용히 Destroy 하면 됩니다.

function TDelSearch.GetBandInfo(dwBandID, dwViewMode: DWORD; var pdbi: TDeskBandInfo): HResult; stdcall;
이건 정말 손이 많이 가는 부분입니다.
IE가 내 밴드에게 와서 이것저것 꼬치꼬치 물어보는 부분이기 때문입니다.
귀찮다고 안가르쳐주면 안되고 하나하나 다 가르쳐 줘야합니다.
질문은 pdbi.dwMask 에 담겨 옵니다.
DBIM_MINSIZE : 최소 사이즈가 얼마니? (IE창이 내 밴드 최소사이즈보다 더 작을 경우는 어쩔수 없이 무시됩니다.)
DBIM_MAXSIZE : 최대 사이즈가 얼마니? (-1로 지정하면 제한이 없어집니다.)
DBIM_INTEGRAL : 사이즈가 변할때 원하는 간격은 얼마니? (그리드 효과를 연상하시면 됩니다. 보통은 1이죠)
DBIM_ACTUAL : 니가 가장 원하는 사이즈는 얼마니? (가능하다면 이 사이즈를 유지하도록 해 줍니다.)
DBIM_TITLE : 니 밴드의 제목이 뭐야? (유니코드로 대답해야 합니다.)
DBIM_MODEFLAGS : 잡다한 기능중에 원하는거 있음 말해봐.
(잡다한 기능 - DBIMF_NORMAL:됐어. DBIMF_VARIABLEHEIGHT:밴드 높이를 조정 가능하게 해줘.
              DBIMF_DEBOSSED: 다른 밴드에 비해 움푹 들어간것 처럼 그려줘.
              DBIMF_BKCOLOR: 배경색을 crBkgnd에 든 값으로 그려줘)
DBIM_BKCOLOR : 배경색깔 칠할까? (pdbi.dwMask := pdbi.dwMask and (not DBIM_BKCOLOR); 아냐 없애줘)


5. 마치자.
-----------------------------

너무 지루한 내용이 되어 버렸네요.
이게 지금 동작은 하지만 문제가 되는 부분이 몇개 있습니다.
1. 검색어입력 Edit 컨트롤에 백스페이스가 안 먹힙니다. (T.T)
  이건 왜 이런지 도통 알 수가 없어요. 분명 IInputObject와 관련이 있을것 같은데 자료가 너무 부족해서 포기했습니다. 아시는 분 꼭 좀 알려주세요.
2. 검색어입력 Edit 컨트롤에 포커스가 넘어올때 SellectAll 설정이 안됩니다.
  이것 또한 원인을 찾지 못하고 있고 대책도 없습니다.
3. 쿨바위에서 오른쪽 버튼을 눌러 밴드감추기를 하면 팝업창이 한 번 더 튀어 나옵니다.
  (델파이로 만들었다고 차별하는거야 뭐야!)

이런 고장난 부분들은 숙제로 남겨두어야만 하겠네요.
혹시라도 수리가 가능하면 다시 꼬리를 달겠습니다.

참고사이트 : http://msdn.microsoft.com/workshop/browser/ext/overview/Bands.asp

 

Posted by SB패밀리