BCB 与 WTL (一)

来源:互联网 发布:微信外卖订餐系统 php 编辑:程序博客网 时间:2024/04/28 03:28

 

WTL是什么? 这是从网上摘录的一段WTL作者的话:
//===================================
WTL是一个基于模板的、专为开发用户界面的程序库。它扩展了ATL,并提供了一些类用来实现应用程序的用户界面、组件和控件。它提供了各种类来支持各种各样的用户界面元素:顶级窗口、MDI、标准控件和通用控件、通用的对话框、属性表以及属性页、GDI对象、UI更新、可卷动的窗口、分割窗口、命令条等等……

WTL的实现使用了和ATL一样的模板架构,所以对于ATL开发者显得很自然。同时它并没有改变或者是隐藏那些Windows相关结构,那些Windows程序员在使用WTL时也不会感到很吃惊。WTL的一个主要设计原则就是避免在没有引用到其他WTL类时,出现不必要的内部依赖。这意味着我们的程序将只包含有我们实际上所使用的代码,除此之外再无其他的东西。加上了模板的使用后,这样做得到的结果就是一些非常小的,不依赖于运行库的程序。

WTL专注于用面向对象的方法来编写Windows的用户界面程序,同时保持代码的尺寸很小。同时,它也为开发者提供了一个很好的基础,可以写新的类来扩展WTL。

最后,我在编写WTL时就希望开发者能够喜欢在开发中使用它。我同样也希望您能够使用它并喜欢上它。
//===================================

最重要的一点,它是开源的.
原先WTL是专为VC写的,其它的C++编译器是无福享用的(因为它基于ATL,而ATL是有版权的,这点M$做得比较绝),好在Borland已经帮我们获得了ATL的使用权,网上又有高手对WTL做了For BCB的修改,使我们在用VCL的同时,又多了一个选择。


好,进入正题,

装备: 

  1. rc资源编辑器 ResEdit http://www.resedit.net   VeryGooooooood的一般人我不告诉他的rc资源编辑器。
  2. WTL for BCB bccSDK http://sourceforge.net/projects/bccsdk/     这个就是传说中高手修改的Win SDK for BCB,有MSN,WMP,MS Speech SDK等, 其中就有我们要用到的ATL和WTL。
  3. BCB5.0 | BCB6.0 | BDS2006 | CB2007   如果不认识这个请跳过此文章,谢谢

准备工作:
设置BCB的Include路径为bccsdk/include/atl和bccsdk/include/wtl, 链接路径为bccsdk/lib。 很简单吧:)

对您的要求:
如果您能理解下面这段代码就没什么问题了,

代码1,模板类

template <class T> class CTpClass{
    
int Fun( void* Data){
        T
* tData= static_cast<T*>(Data);
                
return tData->Fun();
        }
};

代码2,Win SDK & 消息 (下面的代码显示一个蓝色的窗体,上有一大问号)

#include <windows.h>

LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
    
switch(uMsg)
    
{
      
case WM_PAINT:
      
{
          PAINTSTRUCT ps;
          HDC dc
=BeginPaint(hwnd,&ps);

          RECT R;
          GetClientRect(hwnd,
&R);

          HBRUSH bsBlue
=CreateSolidBrush(RGB(0,0,255));
          FillRect(dc,
&R,bsBlue);
          DeleteObject(bsBlue);

          InflateRect(
&R,-50,-50);
          DrawFrameControl(dc,
&R,DFC_CAPTION,DFCS_CAPTIONHELP);

          EndPaint(hwnd,
&ps);
          
return 0;
      }

      
case WM_DESTROY:
          PostQuitMessage(
0);
          
return 0;
      
default:
          
return DefWindowProc(hwnd,uMsg,wParam,lParam);
    }

}


BOOL InitApplication(HINSTANCE hinstance) 
{
    WNDCLASSEX wcx;

    
// Fill in the window class structure with parameters
    
// that describe the main window. 
    wcx.cbSize = sizeof(wcx);          // size of structure
    wcx.style = CS_HREDRAW | CS_VREDRAW;                    // redraw if size changes
    wcx.lpfnWndProc = MainWndProc;     // points to window procedure
    wcx.cbClsExtra = 0;                // no extra class memory 
    wcx.cbWndExtra = 0;                // no extra window memory
    wcx.hInstance = hinstance;         // handle of instance 
    wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION);              // predefined app. icon

    wcx.hCursor 
= LoadCursor(NULL, IDC_ARROW);                    // predefined arrow
    wcx.hbrBackground = GetStockObject(WHITE_BRUSH);                  // white background brush
    wcx.lpszMenuName =  "MainMenu";    // name of menu resource
    wcx.lpszClassName = "MainWClass";  // name of window class 
    wcx.hIconSm = NULL;

    
// Register the window class.
    return RegisterClassEx(&wcx); 
}
 
 
BOOL InitInstance(HINSTANCE hinstance, 
int nCmdShow) 

    HWND hwnd 
= CreateWindow(
        
"MainWClass",        // name of window class 
        "Sample",            // title-bar string 
        WS_OVERLAPPEDWINDOW, // top-level window 

        CW_USEDEFAULT,       
// default horizontal position 
        CW_USEDEFAULT,       // default vertical position 
        CW_USEDEFAULT,       // default width 
        CW_USEDEFAULT,       // default height 
        (HWND) NULL,         // no owner window 
        (HMENU) NULL,        // use class menu 
        hinstance,           // handle of application instance 
        (LPVOID) NULL);      // no window-creation data 
 
    
if (!hwnd) return FALSE;

    
// Show the window and send a WM_PAINT message to the window 
    
// procedure. 
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd); 
    
return TRUE;
}
 

WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance, 
    LPSTR lpCmdLine, 
int nCmdShow) 

    MSG msg; 

    
if (!InitApplication(hinstance)) return FALSE;

    
if (!InitInstance(hinstance, nCmdShow)) return FALSE;

    
while (GetMessage(&msg, (HWND) NULL, 00))
    
{
        TranslateMessage(
&msg); 
        DispatchMessage(
&msg);
    }
 
    
return msg.wParam; 
}

看明白了吗?好,一切就绪,我们开始第一个WTL程序吧:

上面的SDK代码,主要的功能代码是WM_PAINT的消息处理,不过却用了更多的让人头昏脑涨的代码在窗体注册/显示之上,下面我们用WTL实现上面的功能:

在BCB里新建一工程,选Console Wizard, 选项如下:

//---------------------
Source Type:  C++
Use VCL:  No
Use CLX:  No
Multi Threaded:  No
Console Application:  No
//---------------------

在Unit1.cpp里输入下面代码:

#include <atlbase.h>
#include 
<atlapp.h>

CAppModule _Module;

#include 
<atlwin.h>
#include 
<atlframe.h>
#include 
<atlcrack.h>
#include 
<atlmisc.h>

class CMyWin : public CFrameWindowImpl<CMyWin>{
public:
    DECLARE_FRAME_WND_CLASS_EX(
"MainWClass",0,CS_HREDRAW|CS_VREDRAW,COLOR_WINDOW);

    BEGIN_MSG_MAP_EX(CMyWin)
        MSG_WM_PAINT(OnPaint)

        CHAIN_MSG_MAP(CFrameWindowImpl
<CMyWin>)
    END_MSG_MAP()

    
void OnPaint(HDC){
        CPaintDC dc(
*this);

        CRect R;
        GetClientRect(
&R);

        CBrush bsBlue
=CreateSolidBrush(RGB(0,0,255));

        dc.FillRect(R,bsBlue);

        R.InflateRect(
-50,-50);
        dc.DrawFrameControl(R,DFC_CAPTION,DFCS_CAPTIONHELP);
    }

}
;

WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance, 
    LPSTR lpCmdLine, 
int nCmdShow)

    
int nRet;

    _Module.Init(NULL,hinstance);

    
{
        CMyWin mywin;
        mywin.CreateEx();
        mywin.ShowWindow(nCmdShow);

        CMessageLoop MsgLoop;
        nRet
=MsgLoop.Run();
    }


    _Module.Term();
    
return nRet;
}

如果你的Include路径和Lib路径没有设置错误的话,应该可以编译通过了.

对比一下SDK代码,简洁了不少吧。不过和VCL比还有点差距(而且不能RAD),但它有一个比VCL拽的优点:生成的文件非常小,几乎和SDK编写的一样。 so我们的口号是: "SDK的效率,VCL的简洁"

代码看不明白? 没关系,鄙人下回自会分解:)

下回:WTL里的"TApplication","TForm","TStatusBar", "TToolBar" 和 "TCoolBar" 还有一个"alClient属性的TPanel"

 

 

原创粉丝点击