BLOB字段与文本
Delphi BLOB字段中增加了大型文本的处理能力 可以在TBlobField和Strings中自由地交换数据
procedure TBlobField LoadFromStrings(Strings: TStrings)
var
BlobStream: TBlobStream;
begin
BlobStream := TBlobStream Create(Self bmWrite)
try
Strings SaveToStream(BlobStream)
finally
BlobStream Free;
end;
end;
procedure TBlobField SaveToStrings(Strings: TStrings)
var
BlobStream: TBlobStream;
begin
BlobStream := TBlobStream Create(Self bmRead)
try
Strings LoadFromStream(BlobStream)
finally
BlobStream Free;
end;
end;
BLOB字段与Stream对象
因为Delphi中 BLOB字段是通过BLOB流来访问的 所以可以很容易地在BLOB字段和Stream对象之间传递数据 为此 TBlobField对象提供了LoadFromStream和SaveToStream方法
procedure TBlobField LoadFromStream(Stream: TStream)
var
BlobStream: TBlobStream;
begin
BlobStream := TBlobStream Create(Self bmWrite)
try
BlobStream CopyFrom(Stream )
finally
BlobStream Free;
end;
end;
procedure TBlobField SaveToStream(Stream: TStream)
var
BlobStream: TBlobStream;
begin
BlobStream := TBlobStream Create(Self bmRead)
try
Stream CopyFrom(BlobStream )
finally
BlobStream Free;
end;
end;
存取嵌入在OleContainer对象中的OLE服务器的数据
对象链接和嵌入(Object Linking and Embedding 简称OLE) 是一组服务功能 它提供了一种用来源于不同应用程序的信息创建复合文档的强有力方法
通过把图像 图形 表格 声音 注解 文件和其它表示手段描述成对象 用它能在不同软件厂家提供的应用程序中更为容易地交换合成和处理数据它是应用程序的集成更为容易 OLE 支持直观编辑 用户不需切换到不同窗口就能在文档中直接对对象进行 *** 作 改进了 *** 作环境 用户不用再关注应用程序和 *** 作环境 只需关注于使用对象技术的数据和文件 便能完成全部工作
OLE已成为 *** 作系统功能上的一大标准 各大软商纷纷在开发工具中支持OLE 规范 Delphi 提供了OleContainer对象支持OLE窗户应用程序的开发
尽管通过OLE可以用来源于不同应用程序的信息创建复合文档 充分体现以任务 以文档为中心的思想 但是很难分解来自其它应用程序中的嵌入数据 以进行特殊的处理
例如 一套多媒体电子文档管理系统 系统需要数据库管理功能文档编辑功能 全文检索功能等 在文档编辑功能的实现上 如果能利用中文Word 或写字板之类的强大的编辑排版功能 就可以省却重新开发一个文档编辑的费用 使用具有直观编辑的OLE复合文档嵌入Word的DOC数据或RTF数据当然是最佳的选择 但问题在于全文检索系统要求能直接在文档中搜索关键字 因此要求将文档数据从OLE嵌入数据或文档中的本地数据中分离出来
Delphi 的OleContainer部件支持存储OLE对象数据 OLE对象数据包括两部分 OLE类描述信息和OLE服务器嵌入数据 一般说来 OLE服务器嵌入数据是以服务器支持的数据格式存储的 比方说 中文Word 的嵌入数据的格式就是Word 文档的格式 因此 要将文档数据从OLE 嵌入式文档中分离出来就是要访问第二部分数据
我们分析了Delphi 的OleContainer对象存取复合文档的程序 得到分离数据的方法
让我们来看一段OleContainer对象存储数据的程序
procedure TOleContainer SaveToStream(Stream: TStream)
var
DataHandle: HGlobal;
Buffer: Pointer;
Header: TStreamHeader;
R: TRect;
……
begin
……
try
……
if FOldStreamFormat then
begin
R := BoundsRect;
Header PartRect Left := R Left;
Header PartRect Top := R Top;
Header PartRect Right := R Right;
Header PartRect Bottom := R Bottom;
end else
begin
Header Signature := StreamSignature;
Header DrawAspect := FDrawAspect;
end;
Header DataSize := GlobalSize(DataHandle)
Stream WriteBuffer(Header SizeOf(Header))
Buffer := GlobalLock(DataHandle)
try
Stream WriteBuffer(Buffer^ Header DataSize)
finally
GlobalUnlock(DataHandle)
end;
finally
ReleaseObject(TempStorage)
ReleaseObject(TempLockBytes)
end;
end;
程序中 OleContainer对象执行了两次往流中写数据的 *** 作
Stream WriteBuffer(Header Size(Header))
Stream WriteBuffer(Buffer^ Header DataSize)
前一语句是写入OLE类描述信息 后一句语句是写入OLE服务器的嵌入数据 Header是TStreamHeader记录类型的变量 TStreamHeader记录的定义如下
TStreamHeader = record
case Integer of
: ( { 新版OLE对象 }
Signature: Integer;
DrawAspect: Integer;
DataSize: Integer)
: ( { 旧版OLE对象 }
PartRect: TSmallRect)
end;
因此读OLE服务器嵌入数据时 要跳过文件头的TStreamHeader记录 下面就是如何分离OLE服务器嵌入数据的程序
var
Stream : TMemoryStream;
FileStream : TFileStream;
begin
Stream := TMemoryStream Create;
FileStream := TFileStream Create( TEST DOC fmCreate) ;
with OleContainer do
if (State <> osEmpty) then
SaveToStream(Stream)
Stream Seek(Sizeof(TStreamHeader) )
FileStream CopyFrom(Stream Stream Size SizeOf(TStreamHeader))
Stream Free;
FileStream Free;
end;
OleContainer 包含的服务器对象是中文Word 程序中将分离出的数据存储在磁盘文件 TEST DOC 上 如果希望存储在不同的媒介上 可以使用相应的Stream对象 分离的方法类似 但是 这种方法并非对所有的OLE服务器数据都适用 如Windows 附件中的写字板(WordPad)就不行
返回目录 DELPHI基础教程
编辑推荐
Java程序设计培训视频教程
J EE高级框架实战培训视频教程
Visual C++音频/视频技术开发与实战
Oracle索引技术
ORACLE G数据库开发优化指南
Java程序性能优化 让你的Java程序更快 更稳定
C嵌入式编程设计模式
Android游戏开发实践指南
lishixinzhi/Article/program/Delphi/201311/25091
var
f2:Tform2;
begin
try
f2:=Tform2Create(nil);
f2Parent:=TabSheet1;
f2Left:=0;
f2Top:=0;
f2Show;
finally
end;
end;
dll注入( 钩子注入 , 远程线程注入)
shellcode直接注入 (远程线程注入)
还有通过explorer的ShellExecuteHooks注入
QueueUserAPC 注入
方法多的一塌糊涂,我也不好一一列举
给你个简单的远程线程注入dll的代码
procedure InjectDllToProcess(hProcess:DWORD;lpDllName:PCHar);
var
dwWritten : DWORD;
dwThread : DWORD;
dwTid: DWORD;
pArg : Pointer;
begin
pArg := VirtualAllocEx(hProcess, nil, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProcess, pArg, Pointer(lpDllName), 4096, dwWritten);
dwThread := CreateRemoteThread(hProcess, nil, 0, GetProcAddress(GetModuleHandle('KERNEL32DLL'), 'LoadLibraryA'), pArg, 0, dwTid);
WaitForSingleObject(dwThread, INFINITE);
VirtualFreeEx(hProcess, pArg, 0, MEM_RELEASE);
CloseHandle(dwThread);
CloseHandle(hProcess);
end;
这些方法都是病毒的伎俩,研究还好
不然写的程序大多要被杀软kill掉
嵌入汇编用in/out指令是可以的,但是这两条是特权指令,只能在内核模式访问
WIN9x是可以的,从Win2000以后只能用驱动访问若么自己写个驱动只做In/Out指令 *** 作,若么调用WinIO现成的驱动
; 摘要 本文介绍了在Windows平台下串口开发的方法 并给出一个使用Delphi设计的远程数据采集的实例 引言在工业生产实践中 使用PC机对Inprise公司推出的Delphi是一种功能强大的高级编程语言 其具有可视化面向对象的特征 特别适合Windows平台下的图形界面和用户程序的编制 本文就介绍在Windows平台下用Delphi开发串口的方法和使用Delphi设计的一个实现远程串行数据采集的实例 串口工作原理及软件实现方法串口进行通信的方式有两种 同步通信方式和异步通信方式 同步通信方式要求通信双方以相同的时钟频率进行 而且准确协调 通过共享一个单个时钟或定时脉冲源保证发送方和接收方的准确同步 效率较高 异步通信方式不要求双方同步 收发方可采用各自的时钟源 双方遵循异步的通信协议 以字符为数据传输单位 发送方传送字符的时间间隔不确定 发送效率比同步传送效率低 在Windows平台下 Win API支持同步和异步两种I/O *** 作 同步 *** 作的方式的程序设计相对比较简单 但是I/O *** 作函数在I/O *** 作结束前不能返回 这将挂起调用线程 直到I/O *** 作结束 异步 *** 作方式要相对复杂一些 但是可以让I/O *** 作在后台运行 而不会挂起调用线程 这在大数据量通信情况下对改善调用线程的响应速度是相当有效的 同时由于Win x和WinNT下对串行通信的处理不同 这就导致了在Win x下开发的同步方式串行通信程序在NT下会发生工作线程之间的协作阻塞 即当读线程在等待WaitCommEvent的时候 写线程不能正常工作 停在那里 整个程序处于瘫痪状态 这个问题是Windows的API函数处理串行通信的一个BUG 所以对于适应性强的程序都是选择异步方式 下面 本文对在Windows平台下对串口进行开发的方法进行介绍 . 汇编程序直接读写串口汇编语言的编译效率和执行效率都很高 使用汇编语言直接对串口进行 *** 作可以部分弥补串行通信速度较慢的缺陷 具体做法是 用汇编语言编写读 写串口的函数 在通信程序中直接调用 或者在Delphi中直接内嵌汇编程序进行对端口的读写 例如 a mov dx h mov ax eh int h end ; 这样可以达到直接读到端口的效果 但是在WinNT和Win 下 系统使用了保护机制 不允许用户态的程序直接读取端口 所以在WinNT和Win 下 这种方法不能被允许执行 Ring 的用户态的程序要进入Ring 去读写端口必须先提供一个驱动(sys)程序 然后通过DLL导出函数供用户程序调用 显然 这种方法比较不容易实现 . 使用API函数进行串口编程Windows系统通信一般都以WOSA(Windows Open Service Architecture 即Windows开放式服务体系)模型为基础 在此模型中位于上层的应用程序通过调用各种通信API(Application Programming Interfaces 即应用程序接口)与位于下层的设备驱动程序进行数据交换 在Windows平台下 Windows将设备看作是文件进行管理 对设备的 *** 作也可以看作是对文件的 *** 作 Win API提供了CreateFile() WriteFile() ReadFile() WaitForSingleObject() WaitForMultipleObjects() CreateEvent() CreateMutex() CreateSemaphore() CreateThread()等函数 其基本步骤如下 ( ) 利用CreateFile()函数打开串口 该函数有七个参数 其中dwCreationDistribution参数取OPEN_EXISTING 表明打开的串口对应于实际的物理串口 lpFileName参数是要打开的串口名称 如 DwFlagsAndAttributes参数决定对串口的 *** 作是同步 *** 作还是异步 *** 作 DwDesiredAccess参数是访问方式 可取GENERIC_READ或GENERIC_WRITE DwShareMode参数是共享模式 对串口物理设备必须取 LpSecurityAttributes参数是安全属性 取值为NULL DwFlagsAndAttributes是文件属性和标识 一般取值为FILE_ATTRIBUTE_NORMAL 该函数返回串口 *** 作的句柄 ( ) 对该串口句柄对应的设备进行配置 如波特率 数据位 停止位 是否奇偶校验等 这部分首先使用GetCommState()函数得到当前的串口配置信息 将这些信息存放在一个DCB结构中 然后对该DCB结构里面的内容进行重新按要求设置 最后调用SetCommState()函数使修改的设置生效 ( ) 配置串口事件 SetCommMask()函数可以设置多个串口信息事件 其串口的信息事件可以是以下任意的组合 EV_BREAK 在输入时Windows检测到中断 EV_CTS CTS信号改变状态 EV_DSR DSR信号改变状态 EV_ERR 发生线状态错误 EV_RING 检测到振铃指示 EV_RLSD 接收线信号探测状态发生改变 EV_RXCHAR 接收缓冲区里收到字符 EV_RXFLAG 收到事件字符 并放入接收缓冲区 EV_TXEMPTY 输出缓冲区空 ( ) 创建串口监视线程监视串口事件 首先使用WaitForSingleObject() WaitForCommEvent() WaitForMultipleObjects()等等待函数对线程进行控制 当没有数据收发时 将线程阻塞 减少其CPU的资源占用 当有数据收发时 线程自动启动 完成数据的收发 最后调用CreateThread()函数启动线程 ( ) 串口使用结束 用CloseHandle()函数关闭串口 回收资源 由此可见 利用Win API函数编写串口通信程序比较复杂 需要掌握大量的系统和通信知识 其优点是实现的功能强大 应用面广泛 适合编写较为复杂的地层次应用程序 lishixinzhi/Article/program/Delphi/201311/24926
1、delphi支持控制台程序开发;2、delphi支持内嵌汇编。有了这两个条件,开发驱动程序应该不是问题。有关此类问题,请参阅delphi 的语言参考、delphi 的大部头的专著。
实现原理是启动一个应用程序,通过ProcessID得到窗体句柄,然后对其设定父窗体句柄为本程序某控件句柄(本例是窗体内一个Panel的句柄),这样就达成了内嵌的效果。
新建窗体,上面放置一个Panel控件,名为pnlApp,然后按下面代码编写:
unit frmTestEmbedApp;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls;
type
TForm1 = class(TForm)
pnlApp: TPanel;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormResize(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
hWin: HWND = 0;
implementation
{$R dfm}
type
// 存储窗体信息
PProcessWindow = ^TProcessWindow;
TProcessWindow = record
ProcessID: Cardinal;
FoundWindow: hWnd;
end;
// 窗体枚举函数
function EnumWindowsProc(Wnd: HWND; ProcWndInfo: PProcessWindow): BOOL; stdcall;
var
WndProcessID: Cardinal;
begin
GetWindowThreadProcessId(Wnd, @WndProcessID);
if WndProcessID = ProcWndInfo^ProcessID then begin
ProcWndInfo^FoundWindow := Wnd;
Result := False; // 已找到,故停止 EnumWindows
end
else
Result := True; // 继续查找
end;
// 由 ProcessID 查找窗体 Handle
function GetProcessWindow(ProcessID: Cardinal): HWND;
var
ProcWndInfo: TProcessWindow;
begin
ProcWndInfoProcessID := ProcessID;
ProcWndInfoFoundWindow := 0;
EnumWindows(@EnumWindowsProc, Integer(@ProcWndInfo)); // 查找窗体
Result := ProcWndInfoFoundWindow;
end;
// 在 Panel 上内嵌运行程序
function RunAppInPanel(const AppFileName: string; ParentHandle: HWND; var WinHandle: HWND): Boolean;
var
si: STARTUPINFO;
pi: TProcessInformation;
begin
Result := False;
// 启动进程
FillChar(si, SizeOf(si), 0);
sicb := SizeOf(si);
siwShowWindow := SW_SHOW;
if not CreateProcess(nil, PChar(AppFileName), nil, nil, true,
CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil, si, pi) then Exit;
// 等待进程启动
WaitForInputIdle(pihProcess, 10000);
// 取得进程的 Handle
WinHandle := GetProcessWindow(pidwProcessID);
if WinHandle > 0 then begin
// 设定父窗体
WindowsSetParent(WinHandle, ParentHandle);
// 设定窗体位置
SetWindowPos(WinHandle, 0, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOZORDER);
// 去掉标题栏
SetWindowLong(WinHandle, GWL_STYLE, GetWindowLong(WinHandle, GWL_STYLE)
and (not WS_CAPTION) and (not WS_BORDER) and (not WS_THICKFRAME));
Result := True;
end;
// 释放 Handle
CloseHandle(pihProcess);
CloseHandle(pihThread);
end;
procedure TForm1FormClose(Sender: TObject; var Action: TCloseAction);
begin
// 退出时向内嵌程序发关闭消息
if hWin > 0 then PostMessage(hWin, WM_CLOSE, 0, 0);
end;
procedure TForm1FormCreate(Sender: TObject);
const
App = 'C:\Windows\Notepadexe';
begin
pnlAppAlign := alClient;
// 启动内嵌程序
if not RunAppInPanel(App, pnlAppHandle, hWin) then ShowMessage('App not found');
end;
procedure TForm1FormResize(Sender: TObject);
begin
// 保持内嵌程序充满 pnlApp
if hWin <> 0 then MoveWindow(hWin, 0, 0, pnlAppClientWidth, pnlAppClientHeight, True);
end;
end
这个问题其实非常的复杂。
因为Delphi在编写Webbrowser的时候,没有正确地编写快捷键的翻译程序。所以导致出现了这个问题。如果你想要解决这个问题的话。就必须首先改正Webbrowser的这个Bug
解决方法如下:
首先从你的Delphi源码目录中找出OleCtrlspas文件。然后复制这个文件到你工程目录,并添加到你的工程中。
修改你复制的OleCtrlspas文件,首先从这个文件中找到TOleControlWndProc函数,然后在这个函数中找到这一行:
WinMsgHWnd := Handle;
将此行改为
WinMsgHWnd := GetFocus;
因为Webbrowser可能存在焦点定位错误的问题。所以,同样需要复制SHDocVwpas文件到你的目录,并添加到你的工程中。并在重载TWebbrowser的WndProc函数:
procedure TWebbrowserWndProc(var Msg: TMessage);begin
try
case MsgMsg of
WM_SETFOCUS:
begin
GetParentForm(Self)ActiveControl := nil; WinApiWindowsSetFocus(Handle); Exit;
end;
CM_VISIBLECHANGED,WM_MOUSEACTIVATE:
if TWinControl(Self)Visible then
GetParentForm(Self)ActiveControl := nil;
end;
except
end;
inherited;
end;
另外,你如果使用的是Delphi XE2 以上的版本,OleCtrls单元的名称可能为VclOleCtrls。你可能需要在ShdocVw单元中引用Forms、Messages与Controls单元。
以上就是关于DELPHI基础教程:开发Delphi对象式数据管理功能(五)[4]全部的内容,包括:DELPHI基础教程:开发Delphi对象式数据管理功能(五)[4]、delphi tab内嵌form 除了设置parent还有别的吗、delphi编程序如何注入其它程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)