C++Builder 程序员博客
3 Apr
initialization ///这里是不是相当于CB的__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)啊?
hMapFile := OpenFileMapping(FILE_MAP_WRITE, False, cMapFileName);
DoClear := hMapFile = 0;
if hMapFile = 0 then
hMapFile := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE,
0, SizeOf(TShareData), cMapFileName);
P := MapViewOfFile(hMapFile, FILE_MAP_WRITE, 0, 0, 0);
if DoClear then FillChar(P^, SizeOf(TShareData), 0);
ControlAtomString := Format('ControlOfs%.8X%.8X', [GetModuleHandle(nil), GetCurrentThreadID]);
ControlAtom := GlobalAddAtom(PChar(ControlAtomString));
RM_GetObjectInstance := RegisterWindowMessage(PChar(ControlAtomString));
if P^.DestWnd <> 0 then
begin
GetWindowThreadProcessId(P^.DestWnd, DestPID);
if DestPID = GetCurrentProcessId then
begin
DestProcess := True;
UtilWindowClass.hInstance := HInstance;
RegisterClass(UtilWindowClass);
P^.MsgWnd := CreateWindowEx(
WS_EX_TOOLWINDOW, // extended window style
UtilWindowClass.lpszClassName, // pointer to registered class name
UtilWindowClass.lpszClassName, // pointer to window name
WS_POPUP, // window style
0, // horizontal position of window
0, // vertical position of window
0, // window width
0, // window height
0, // handle to parent or owner window
0, // handle to menu, or child-window identifier
HInstance, // handle to application instance
nil); // pointer to window-creation data
PostMessage(P^.HostWnd, CM_MSGWNDCREATED, P^.MsgWnd, 1);
end;
end;
finalization //这里呢?相当于CB的哪里啊?难道进CLOSE事件????
if DestProcess then
begin
DestroyWindow(P^.MsgWnd);
PostMessage(P^.HostWnd, CM_MSGWNDCREATED, P^.MsgWnd, 0);
end;
GlobalDeleteAtom(ControlAtom);
ControlAtomString := '';
UnmapViewOfFile(P);
CloseHandle(hMapFile);
finalization ——相当于析构函数吧?
不是的,delphi的initialization和finalization都是对Unit的,相当于CPP文件或H文件。
程序一开始就执行所要调用Unit的initialization,程序结束就执行所要调用Unit的finalization。
3 Apr
Delphi: Canvas.Brush.Style := bsClear;
BCB: Canvas->Brush->Style = bsClear;
在写控件的时候,同样的代码,执行效果确实很不同.
Delphi执行了,背景色是白色的
BCB执行了,背景色的黑色的
谁遇到过..
这个取决于Brush->Color的设置。
Canvas->Brush->Color = clWhite;
Canvas->Brush->Style = bsClear;
这样写,背景成了黑色的
打算用别的方法绘制了,谢谢你们
2 Apr
//显示数据
//SQLDataSet1.First;
SQLDataSet1->First();
//while not SQLDataSet1.Eof do
//while(!SQLDataSet1->Eof)
//begin
{
//with ListView1.Items.Add do
TListItem *Item=ListView1->Items->Add();
//begin
//Caption := IntToStr(j);
Item->Caption=IntToStr(j);
//for i := 0 to SQLDataSet1.Fields.Count - 1 do
for(i=0;i <=SQLDataSet1->Fields->Count-1;i++)
//SubItems.Add(SQLDataSet1.Fields[i].AsString);
Item->SubItems->Add(SQLDataSet1->Fields[i]->AsString);//这句编译通不过
//end;
//inc(j);
j++;
//SQLDataSet1.Next;
SQLDataSet1->Next();
//end;
}
编译器报这个错误:
[BCC32 Error] Unit1.cpp(76): E2288 Pointer to structure required on left side of -> or ->*
我刚刚接触cb和dbexpress,这段代码是参考别人的。请高手指教一下吧!先谢过了~
Item->SubItems->Add(SQLDataSet1->Fields->Fields[i]->AsString);//这句编译通不过
多谢了,这么写就解决了。
请问你有没有dbexpress的帮助文档或者和示例程序呢?可不可以发给我一些?
我实在搜不到,官网上也没有找到。
招聘C++Builder的为什么这么少?从Delphi转C++Builder再转VC++难吗?
大学毕业了,课没上几节,唯独钟爱Delphi,但是发现招聘Delphi的没有多少公司,再由于也想做游戏开发,所以想学C++,因为大部分网游都是C++开发的,再者招聘C++Builder的也不多,所以我想从Delphi转向C++Builder,然后再转向VC++
请问这种的难易程度有多高?或者俄打个比方说明一下
并说明为什么招聘VC++的多,而c++Builder的这么少呢?
我装的CODEGEAR RAD STUDIO 2009,三样都有,用了C++BUILDER后,感觉开发确实简单很多。我在网上查用C++写得记事本得源码,都查不到。我是怕只学C++Builder碰不到更底层得东西,那么学到得也就不多
26 Dec
如何在c++builder中引用delphi类?
额,应该是可以直接add to project的
PS:我试过直接将delphi的form加到bcb的工程里编译并调用
把Delphi的单元添加到工程当中,然后会生成一个.hpp的头文件,然后include进来就可以使用了.
1、选择Projet|Add to Project
2、从Add to Project对话框中选择CPP、C、PAS、RES、LIB或OBJ。对于Delphi单元,选择PAS。
3、浏览目录并选择加入项目所需要的文件。
4、找到所需的文件后,单击Open完成。无须以任何方式进一步处理Pascal文件。
直接加入工程即可。
呵呵,楼上都说了
cnpack里有许多pas文件,请问如何调用呢?
/* 貌似cnpack已经做成控件了吧,直接用就是啦! 若是单独调用某个单元里面的函数,上面已经有 方法介绍了,就是将pas单元AddTo Project生成 对应的hpp文件,若对应的hpp文件已经有了,就 直接包含进来,然后调用里面的函数,或者其他东东! */
18 Dec
function encrypt_str(Src: string; Key: string; Encrypt: Boolean; m_brand: boolean = true): string;
var
idx: integer;
KeyLen: Integer;
KeyPos: Integer;
offset: Integer;
dest: string;
SrcPos: Integer;
SrcAsc: Integer;
TmpSrcAsc: Integer;
Range: Integer;
begin
try
KeyLen := Length(Key);
if KeyLen = 0 then key := 'wangy lsy dmp';
KeyPos := 0;
SrcPos := 0;
SrcAsc := 0;
Range := 256;
if Encrypt then
begin
Randomize;
offset := 18;
if m_brand then
offset := Random(Range);
dest := format('%1.2x', [offset]);
for SrcPos := 1 to Length(Src) do
begin
SrcAsc := (Ord(Src[SrcPos]) + offset) mod 255;
if KeyPos < KeyLen then KeyPos := KeyPos + 1 else KeyPos := 1;
SrcAsc := SrcAsc xor Ord(Key[KeyPos]);
dest := dest + format('%1.2x', [SrcAsc]);
offset := SrcAsc;
end;
end
else
begin
offset := StrToInt('$' + copy(src, 1, 2));
SrcPos := 3;
repeat
SrcAsc := StrToInt('$' + copy(src, SrcPos, 2));
if KeyPos < KeyLen then KeyPos := KeyPos + 1 else KeyPos := 1;
TmpSrcAsc := SrcAsc xor Ord(Key[KeyPos]);
if TmpSrcAsc <= offset then
TmpSrcAsc := 255 + TmpSrcAsc - offset
else
TmpSrcAsc := TmpSrcAsc - offset;
dest := dest + chr(TmpSrcAsc);
offset := srcAsc;
SrcPos := SrcPos + 2;
until SrcPos >= Length(Src);
end;
Result := Dest;
except
showmessage(src);
end;
end;
AnsiString encrypt_str(AnsiString Src, AnsiString Key, bool Encrypt, bool m_brand = true) { int idx,KeyLen,KeyPos,offset; AnsiString dest; int SrcPos,SrcAsc,TmpSrcAsc,Range; try { KeyLen = Key.Length(); if (KeyLen == 0 ) Key = "wangy lsy dmp"; KeyPos = 0; SrcPos = 0; SrcAsc = 0; Range = 256; if (Encrypt) { Randomize(); offset = 18; if (m_brand) offset = Random(Range); dest.sprintf("%1.2x", offset); for (SrcPos = 1 ; SrcPos <= Src.Length() ; SrcPos ++) { SrcAsc = (((unsigned char)Src[SrcPos]) + offset) % 255; if (KeyPos < KeyLen) KeyPos = KeyPos + 1; else KeyPos = 1; SrcAsc = SrcAsc ^ (unsigned char)Key[KeyPos]; AnsiString tmpStr; tmpStr.sprintf("%1.2x", SrcAsc); dest = dest + tmpStr; offset = SrcAsc; } } else { offset = StrToInt("0x" + Src.SubString(1, 2)); SrcPos = 3; do{ SrcAsc = StrToInt("0x" + Src.SubString( SrcPos, 2)); if (KeyPos < KeyLen ) KeyPos = KeyPos + 1; else KeyPos = 1; TmpSrcAsc = SrcAsc ^ (unsigned char)Key[KeyPos]; if (TmpSrcAsc <= offset ) TmpSrcAsc = 255 + TmpSrcAsc - offset; else TmpSrcAsc = TmpSrcAsc - offset; dest = dest + AnsiString((char)TmpSrcAsc); offset = SrcAsc; SrcPos = SrcPos + 2; }while (SrcPos < Src.Length()); } return dest; } catch(…){ ShowMessage(Src); } }
15 Dec
procedure TForm1.Button1Click(Sender: TObject);
begin
Webbrowser1.Navigate('D:\a.html');
//启动一个网站的网页
end;
procedure TForm1.Button2Click(Sender: TObject);
var
Range:IHTMLTxtRange;
begin
Range := ((WebBrowser1.Document as IHTMLDocument2).body as
IHTMLBodyElement).createTextRange;
Range.collapse(False);
Range.pasteHTML(' <br> <b>大家好,我是老李,csdn Id Laoli </b>');
//加入你要加的东西
end;
/* // WebBrowser->Navigate(L"D:\a.html"); sorry,这句路径在C++中应该是 WebBrowser->Navigate(L"D:\\a.html") ; */
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Webbrowser1->Navigate('D:\\a.html');
}
楼上正解
非常感谢!
15 Dec
procedure a(s1: String); external 'ABC.dll'
procedure b(s1, s2: String); external 'ABC.dll'
procedure c; external 'ABC.dll'
procedure TForm1.WebBrowser1BeforeNavigate2(Sender: TObject;
const pDisp: IDispatch; var URL, Flags, TargetFrameName, PostData,
Headers: OleVariant; var Cancel: WordBool);
var
urlStr, headStr: String;
i, ipos: Integer;
IE: IWebbrowser2;
htmlDoc: IHTMLDocument2;
iColl: IHTMLElementCollection;
field: IHTMLElement;
iInputElement: IHTMLInputElement;
iSelectElement: IHTMLSelectElement;
begin
urlStr := URL;
i := 0;
Form1.Cursor := crHourGlass;
WebBrowser1.Cursor := crHourGlass;
ipos := Pos('_timewe_wapie_=',urlStr);
if ipos>0 then begin
headStr := Copy(urlStr,ipos+15,Length(urlStr)-ipos-14);
if strtofloatdef(headStr,0) <> strtofloatdef(headStr,1) then begin
i := 1;
headStr := Copy(urlStr,ipos+15,i);
while strtofloatdef(headStr,0) = strtofloatdef(headStr,1) do begin
Inc(i);
headStr := Copy(urlStr,ipos+15,i);
end;
headStr := Copy(urlStr,ipos+15,i-1);
end;
a(headStr);
i:=StrToInt(headStr);
IE := pDisp as IWebBrowser2;
if IE <> nil then begin
try
htmlDoc := IE.Document as IHTMLDocument2;
if htmlDoc <> nil then begin
iColl := htmlDoc.all.tags('INPUT') as IHTMLElementCollection;
if Assigned(IColl) then
for i := 0 to iColl.length-1 do
begin
field := iColl.item(i, 0) as IHTMLElement;
if Assigned(field) then
begin
iInputElement := iColl.item(i, 0) as IHTMLInputElement;
if Assigned(iInputElement) then
if iInputElement.type_ <> 'hidden' then begin
b(iInputElement.name, iInputElement.value);
end;
end;
end;
iColl := htmlDoc.all.tags('SELECT') as IHTMLElementCollection;
if Assigned(IColl) then
for i := 0 to iColl.length-1 do
begin
field := iColl.item(i, 0) as IHTMLElement;
if Assigned(field) then
begin
iSelectElement := field as IHTMLSelectElement;
if Assigned(iSelectElement) then begin
b(iSelectElement.name, iSelectElement.value);
end;
end;
end;
end;
except on E: Exception do
end;
end;
c;
end;
end;
没人会,不会吧?
太长了,其实都差不多
//前面是ABC这个dll里面3个导出函数的声明 void __declspec(dllimport) __stdcall a(String s1); void __declspec(dllimport) __stdcall b(String s1,String s2); void __declspec(dllimport) __stdcall c(void) ; // 下面的代码一样,写在BCB的CppWebBrowser1的那个OnBeforeNavigate2事件中 String urlStr , headStr ; int i,ipos; IWebBrowser2* IE ; IHTMLDocument2* htmlDoc; IHTMLElementCollection* iColl; IHTMLInputElement* iInputElement; IHTMLSelectElement* iSelectElement; urlStr = URL; i=0; Form1->Cursor = crHourGlass; WebBrowser1->Cursor = crHourGlass; ipos = urlStr.Pos("_timewe_wapie_="); if(ipos>0) { headStr =urlStr.SubString(ipos+15,urlStr.Length()-ipos-14); while(StrToFloatDef(headStr,0) != StrtoFloatDef(headStr,1)) { i =1 ; headStr = urlStr.SubString(ipos+15,i); } headStr = urlStr.SubString(ipos+15,i-1); } a( headStr); i =StrToInt(headStr); IE = dynamic_cast<IWebBrowser2*>(pDisp); if(IE) { try { htmlDoc=dynamic_cast<IHTMLDocument2*>(IE->Document); if(htmlDoc) { iColl = dynamic_cast<IHTMLElementCollection*>(htmlDoc->all->tags("INPUT")) ; if(iColl) { for( i = 0 ; i<=iColl->length-1 ; ++i) { field = dynamic_cast<IHTMLElement*>(iColl->item(i,0)) ; if(field) { iInputElement = dynamic_cast<IHTMLInputElement*>(iCol->item(i,0)); if(iInputElement) { if(iInputElement->type!=WideString("hidden")) { b(iInputElement->name,iInputElement->value); } } } } iColl = dynamic_cast<IHTMLElementCollection*>(htmlDoc->all->tags("SELECT")) ; if(iColl) { for( i = 0 ; i<=iColl->length-1 ; ++i) { field = dynamic_cast<IHTMLElement*>(iColl->item(i,0)) ; if(field) { iInputElement = dynamic_cast<IHTMLSelectElement*>(iCol->item(i,0)); if(iInputElement) { b(iInputElement->name,iInputElement->value); } } } } } } catch(Exception& e) { // ……….. } } c() ;
楼上很强
__stdcall >> pascal
哈哈
我正在把我的D转到C
帮你看下
就当俺啥也没说
人家都搞好了
12 Dec
下面是delphi编的,要转换成builder,哪位帮帮我呢?
function TMainForm.ExportToExcel(DSet:TDataSet):Integer;
var
i,j:integer;
f:TextFile;
sl:TStringList;
begin
Result := 1;
with DSet do
begin
if (not DSet.Active) then
Exit;
if (not SaveDialog.Execute) then
Exit;
AssignFile(f,SaveDialog.FileName);
try
Rewrite(f);
except
ShowInfo('保存文件失败!');
WriteErrorLog('保存文件失败:' + SaveDialog.FileName);
CloseFile(f);
Exit;
end;
Screen.Cursor := crHourGlass;
DisableControls;
sl := TStringList.Create;
sl.Clear;
for i:=0 to FieldCount-1 do
begin
if (Fields[i].Visible) then
sl.Add(Fields[i].DisplayLabel);
end;
writeln(f,sl.CommaText);
First;
for j:=0 to RecordCount-1 do
begin
sl.Clear;
for i:=0 to FieldCount-1 do
begin
if (Fields[i].Visible) then
sl.Add(VarToStr(Fields[i].Value));
end;
writeln(f,sl.CommaText);
Next;
end;
sl.Free;
CloseFile(f);
EnableControls;
Screen.Cursor := crDefault;
end;
Result := 0;
end;
同意
同意上面3位
步骤是这样的
1、选择Projet|Add to Project
2、从Add to Project对话框中选择CPP、C、PAS、RES、LIB或OBJ。对于Delphi单元,选择PAS。
3、浏览目录并选择加入项目所需要的文件。
4、找到所需的文件后,单击Open完成。无须以任何方式进一步处理Pascal文件。
直接加到工程中不就好了。
5 Dec
var
FlxpTrayIcon: TlxpTrayIcon;
{ TlxpTrayIcon }
constructor TlxpTrayIcon.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FlxpTrayIcon := Self;
……
end
procedure SetAnimatedIcon(Wnd: HWND; Msg, idEvent: UINT; dwTime: DWORD); stdcall;
begin
if Msg = WM_TIMER then with FlxpTrayIcon.NotifyIconData do
begin
if hIcon = 0 then hIcon := FlxpTrayIcon.FTrayIcon.Handle
else hIcon := 0;
Shell_NotifyIcon(NIM_MODIFY, @FlxpTrayIcon.NotifyIconData);
end;
end;
………
TimerHandle := SetTimer(0, 0, FInterval, @SetAnimatedIcon)
……..
最近在看一本《delphi 精要》的书,其中实现了一个TRAYICON的原代码,其中定时器是用SetTimer实现的,
我把他改写为以下代码:
void CALLBACK SetAnimatedIcon(HWND Wnd,UINT Msg,UINT idEvent,DWORD dwTime)
{
if(Msg == WM_TIMER)
{
if(NotifyIconData.hIcon==NULL)
{
NotifyIconData.hIcon = FTrayIcon->Handle;
}
else
NotifyIconData.hIcon = NULL;
Shell_NotifyIcon(NIM_MODIFY,&NotifyIconData);
}
}
//—————————————————————————
问题1:NotifyIconData是类中的私有变量,他是如何可以在外部函数中可以直接使用的?
问题2:如何在组件实现单元中声明一个实例让他指向自己?
如果有空,最好帮我改写一下DELPHI的实现代码?
BCB中的原码实现TRAYICON我看了的,它没有使用的是SETTIMER,而是用的定时器.
1. 友元(friendly)
2. (没明白意思)
SetAnimatedIcon写成类的成员函数不就可以了?
将外部的某个类声明为friend,外部类就可以访问自己的私有变量和方法了。
SetTimer跟定时器没有什么区别
如果不用回调函数:
#include <vcl.h> #pragma hdrstop #include "Unit1.h" //————————————————————————— #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; void __fastcall TForm1::WndProc(Messages::TMessage &Message) //重载WM_TIMER消息,楼主也可以用消息映射宏来做 { TForm::WndProc(Message); if(Message.Msg==WM_TIMER && Message.wParam==1) { ShowMessage("AA");// } } //————————————————————————— __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //————————————————————————— void __fastcall TForm1::Button1Click(TObject *Sender) { ::SetTimer(Handle,1,1000,NULL);// } //————————————————————————— void __fastcall TForm1::Button2Click(TObject *Sender) { ::KillTimer(Handle,1);// } //—————————————————————————
SetTimer要求有一个函数指针,执行自定义流程
我在API中是这样调用的:
SetTimer(NULL,NULL,FInterval,(TIMERPROC)SetAnimatedIcon)
就是我定义的:
void CALLBACK SetAnimatedIcon(HWND Wnd,UINT Msg,UINT idEvent,DWORD dwTime)
但这个函数不在类中,却要用到私有变量,
请注意DELPHI中的FlxpTrayIcon对象,这个对象在类外部定义,
var
FlxpTrayIcon: TlxpTrayIcon;
但在DELPHI的函数中却能引用私有变量,不知道它是怎么实现的?
如果需要传递一个附加数据到该过程当中,个人建议使用多媒体定时器
关于多媒体定时器,可以参考下面的贴子当中的代码:http://topic.csdn.net/u/20070806/23/43870f4d-0e26-4320-9d0a-2623e3d0d6a1.html
VOID CALLBACK TimerProc(
HWND hwnd, // handle of window for timer messages
UINT uMsg, // WM_TIMER message
UINT idEvent, // timer identifier
DWORD dwTime // current system time
);
路过,学习……
自己搞定了
是要用到友员,将SetAnimatedIcon设为一个友员函数
friend void CALLBACK SetAnimatedIcon(HWND Wnd,unsigned int Msg,unsigned int idEvent,unsigned long dwTime);
然后在组件实现单元,申明一个指针,
TLZWTrayIcon *FLZWTrayIcon;
在构造函数中指向自己,FLZWTrayIcon = this;
然后就可以在函数中用到自己的私有变量了:
void CALLBACK SetAnimatedIcon(HWND Wnd,UINT Msg,UINT idEvent,DWORD dwTime)
{
if(Msg == WM_TIMER)
{
if(FLZWTrayIcon->NotifyIconData.hIcon==NULL)
{
FLZWTrayIcon->NotifyIconData.hIcon = FLZWTrayIcon->FTrayIcon->Handle;
}
else
FLZWTrayIcon->NotifyIconData.hIcon = NULL;
Shell_NotifyIcon(NIM_MODIFY,&FLZWTrayIcon->NotifyIconData);
}
}
//—————————————————————————
这样调用SETTIMER时,就没有问题了。谢谢僵哥,你的多媒体定时器,我有时间再来研究。
谢谢各位,结帖了。