⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 9920.txt

📁 关于编程技术技巧的文章
💻 TXT
📖 第 1 页 / 共 3 页
字号:
{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
Application.OnMessage:=AppMessage;
//捕捉消息:将程序的收到消息事件与消息过滤过程关联起来
end;

procedure TForm1.AppMessage(var Msg:TMsg;var Handled:Boolean);
begin
if (Msg.message=WM_LButtonDown) and 
//如果鼠标左键按下的话
(DefWindowProc(Handle,WM_NCHitTest,
0,GetMessagePos)=HTClient) and
//判断光标是否在客户区内
((GetKeyState(vk_CONTROL) < 0) 
//检测“Ctrl”键是否按下
then
begin
SendMessage(Handle,WM_NCLButtonDown,
HTCaption,GetMessagePos);
//发送鼠标在标题栏内按下的消息
Handled:=true;
end;
end;

---- 方 法 三: 

---- 直 接 向 窗 体 发 送 一 条“wm_SysCommand” 消 息,
需 要 使 用 未 归 档 的“sc_DragMove” 标 志, 定 义 如
下: 

const
sc_DragMove:LongInt=$F012;

---- 我 们 只 能 向TWinControl 派 生 组 件 发 送 该 消 息, 而 且 只
能 响 应 鼠 标 按 下 事 件, 因 为 系 统 会 在 此 时 捕 获 鼠 标( 当 
释 放 鼠 标 键 时, 拖 动 操 作 是 没 有 意 义 的)。 

---- 例 程 如 下: 

.
. 
const
sc_DragMove:longint=$F012;

implementation

{$R *.DFM}

procedure TForm1.FormMouseDown
(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if ssCtrl in Shift then
//判断“Ctrl”键是否按下
Begin
ReleaseCapture;
//释放鼠标事件的对象
(Sender as TWinControl).PerForm(wm_SysCommand,
sc_DragMove,0);
//发送消息
end;
end;

---- 这 种 方 法 适 用 与 窗 体 与 组 件, 如 想 移 动 组 件, 将 其
“OnMouseDown” 事 件 写 成 与Form 的 “OnMouseDown” 事 件 一 样 即 
可。 如 只 想 移 动 窗 体 可 按 以 下 方 法 编 写 代 码: 

.
.
procedure TForm1.FormMouseDown
(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if SsCtrl in Shift then
Begin
ReleaseCapture;
SendMessage(handle,wm_SysCommand,
sc_DragMove,0);
end;
end;

---- 运 行 结 果: 

---- 按 下“Ctrl” 键 拖 动 鼠 标 即 可 移 动 窗 体。 

---- 总 结: 

---- 要 实 现 无 标 题 窗 体 的 移 动 有 很 多 种 方 法, 还 可 以 
通 过 检 测 鼠 标 的 位 置( 坐 标) 来 确 定Form 的“left” 与“top  
值 等 方 法, 在 此 不 再 详 细 举 例. 

---- 以 上 程 序 均 在Delphi 3.0 下 编 译 通 过。 
                 
***********************************************************
          
                TDBGrid控件中对多个记录的处理

               山东济宁市建设南路76号   唐成斌

---- DELPHI 的TDBGrid 控 件 主 要 用 来 处 理 数 据 表,它 的 属 性 
中 有 一 个dgMultiSelect, 若 此 属 性 设 定 为TRUE, 则 可 以 选 中 
多 个 记 录( 可 用CTRL + 鼠 标 左 键 选 择 多 个 记 录)。 对 选 
中 的 多 个 记 录 可 以 有 以 下 几 种 处 理 方 式, 比 较 简 单 的 
两 种 是: 清 除 所 有 的 选 择 记 录 可 用DBGrid1.SelectedRows.Clear  
语 句; 删 除 所 有 的 选 择 记 录 可 用DBGrid1.SelectedRows.Delete 语 
句。 但 如 果 想 获 得 选 中 的 所 有 记 录 的 其 他 信 息, 比 如, 
在 单 独 的 一 个 窗 体 中 显 示 用 户 选 择 的 记 录 的 第 一 个 字 
段 的 内 容( 如 所 有 选 择 的 姓 名) 如 何 处 理 呢 ? 这 就 要 使 
用 书 签 功 能 了, 下 面 是 笔 者 编 写 的 一 个 程 序 中 的 过 程, 
用 来 将 用 户 选 择 的 多 个 记 录 集 中 显 示 在 另 外 一 个 窗 体 
中 ( 笔 者 使 用 的 是DELPHI4), 供 参 考 使 用。 

procedure GetSelectedRecord
(DataSet : TDataSet; FieldName : String;
BookmarkList : TBookmarkList; Strings : TStrings);
//这个过程中的参数分别为:数据表、字段名称、
书签、用来保存所选字段内容的
//字符串(用于将内容传递到另
一个单独窗体中的TLIST控件中)
var
I: Integer;
bm : TBookMark;
begin
Strings.Clear;
with Dataset do begin
DisableControls;
bm := GetBookMark;
try
//每个选择的记录都有一个书签标志,
这就为处理它们提供了条件
for I := 0 to BookmarkList.Count - 1 do begin
Bookmark := BookmarkList[I];
Strings.Add(DataSet.FindField(fieldname).AsString);
end;
finally
GotoBookMark(bm);
FreeBookMark(bm);
EnableControls;
end;
end;
end;

调用举例:
GetSelectedRecord(Table1, 'NAME', DBGrid1.SelectedRows, 
Form2.ListBox1.Items);
 
***********************************************************
 
                   用MFC实现在字段中存储变长数组

                                黄晓润 

---- 在 数 据 库 应 用 时, 有 时 会 遇 到 这 样 的 情 况: 记 录 的 某 
项 信 息 由 变 长 数 组 构 成。 这 时 传 统 方 法 是 建 立 一 个 新 表, 
并 通 过 表 间 的 关 系 来 记 录 将 相 应 数 据 关 联 起 来; 但 是 这 
样 实 现 相 对 比 较 复 杂, 而 且 也 不 符 合 思 维 逻 辑。 由 于 该 
数 组 整 个 构 成 记 录 的 一 个 具 体 项, 因 此 如 果 能 够 将 它 作 
为 一 个 字 段 则 更 加 直 观 些, 同 时 在 一 些 情 况 下 也 比 较 容 
易 处 理。 那 么, 下 面 将 向 您 提 供 一 种 这 样 的 方 法。 为 了 说 
明 上 的 方 便, 我 首 先 假 定 了 下 面 的 需 求: 

---- 在 个 人 简 历 数 据 表 中, 需 要 将 工 作 经 历 分 为 起、 止 时 
间、 单 位、 职 位 等 信 息。 

---- 在 这 种 情 况, 可 以 分 别 建 立 个 人 简 历 和 工 作 经 历 两 
个 表 并 将 之 通 过 关 键 字 进 行 关 联, 从 而 达 到 要 求。 但 也 
可 以 采 用 只 建 立 一 个 表 的 方 式 来 完 成 数 据 的 管 理 

---- 那 么 如 何 完 成 呢 ? 下 面 将 给 出 具 体 的 实 现。 

---- 首 先 建 立 一 个 表Person, 记 录 包 含 个 人 简 历 需 要 的 各 
个 字 段, 将 工 作 经 历 作 为 一 个 字 段, 其 类 型 为Image( 在Access 
数 据 库 中 为"OLE 对 象")。 下 面 新 建 类CPersonRs。 将 它 与 表Person 
对 应 起 来, 并 将 m_dResume 对 应 到 字 段 工 作 经 历 中,m_dResume 
的 类 型 为CByteArray 。 下 面 我 们 来 定 义 工 作 定 义 的 基 本 结 构: 

class CResumeItem
{
public:
COleDateTime m_timeBegin;
COleDateTime m_timeEnd;
COleDateTime m_strCompany;
COleDateTime m_strTitle;

Void Serialize( CArchive& ar )
};
typedef CArray< CResumeItem, CResumeItem& > CResume;

---- 在CPersonRs 中 定 义 下 面 的 函 数 

CPersonRs
{
……
CByteArray m_dResume;
……
void SetResume( CString strName, CResume& resume );
void GetResume( CString strName, CResume& resume );
};

并在相应的文件给出相应的函数的实现;
void CResumeItem::Serialize( CArchive& ar )
{
if ( ar.IsLoading() )
{
ar > > m_timeBegin
> > m_timeEnd
> > m_strCompany
> > m_strTitle;
}
else
{
ar < < m_timeBegin
< < m_timeEnd
< < m_strCompany
< < m_strTitle;
}
}

函数SetResume和GetResume实现如下:
void CPersonRs::SetResume
( CString strName, CResume& resume )
{
…………//根据strName定位到相应的记录
Edit();
CMemFile memFile;
CArchive ar( &memFile, CArchive::store );
Resume.Serialize( ar );
ar.Close();
DWORD dwSize = memFile.GetLength();
LPBYTE lpInfo = memFile.Detach( );
m_dResume.SetSize( dwSize );
memcpy( m_dResume.GetData(),lpInfo,dwSize);
SetFieldNull( &m_dResume, FALSE );
SetFieldDirty( &m_dResume );
ASSERT( CanUpdate() );
Update( );
free( lpInfo ); 
}

void CPersonRs::GetResume
( CString strName, CResume& resume )
{
…………//根据strName定位到相应的记录
LPBYTE lpInfo;
DWORD dwSize;
dwSize = m_dResume.GetSize();
lpInfo = m_dResume.GetData();
memFile.Attach( lpInfo, dwSize );
CArchive ar( &memFile,CArchive::load );
resume.Serialize( ar );
ar.Close();
memFile.Detach( ); 
}

---- 通 过SetResume 和GetResume 可 以 方 便 地 将Resume 的 内 容 读 出 
或 写 入 到 记 录 的 工 作 经 历 字 段 中, 而 且 更 新 也 相 当 方 便。 
这 样 是 就 可 以 在 工 作 经 历 字 段 任 意 个 工 作 经 历 项, 而 且 
由 于 是 在 一 个 表, 也 省 去 了 多 表 造 成 的 麻 烦。 

---- 不 过, 最 后 需 要 声 明 的 是, 上 述 例 子 的 情 况 根 据 实 际 
需 要 可 能 用 多 表, 但 这 里 只 是 借 它 说 明 这 样 一 种 实 现 方 
法, 也 许 你 会 在 某 些情 况 下 这 些 会 相 当 简 单 些。 本 文 也 只 
给 出 实 现 的 关 键 代 码, 对 于 如 何 使 用MFC 访 问 数 据 库、 序 
列 化 机 制 可 以 参 见VC 的 相 应 文 档。

***********************************************************
  
                  BC++ Builder 3.0中各种资源的利用

                     烟台南大街建行科技部   李进

---- 在 编 写 程 序 的 过 程 中, 经 常 要 用 到 各 种资 源。 比 如 说, 
想 给 自 己 的 程 序 换 个 自 己 的图 标, 使 用 一 些 活 泼 的 光 标 来 
增 加 趣 味 性,播 放 一 些 声 音 和 动 画 文 件, 或 者 使 用 别 人 写好
的 程 序 来 实 现 某 个 功 能。 我 们 往 往 希 望 将这 些 资 源 直 接 放 
到EXE 文 件 中 以 形 成 一 个 单 独的 可 执 行 文 件, 这 就 存 在 一 个 
如 何 在 运 行 时访 问 和 使 用 这 些 资 源 的 问 题。 

---- 在 编 译 期 间, 这 就 要 用 到 一 种 文 件, 以.rc 结 尾 的 资 源 
定 义 文 件。 

---- 一: RC 文 件 

---- rc 文 件 是 个 文 本 文 件, 它 的 格 式 很 简 单,按 如 下 格 式 定 义: 

---- 资 源 标 识 符 资 源 类 型 资 源 的 路 径 

---- 以 下 的 rc 文 件 定 义 了 一 个 声 音 资 源, 两个 光 标 资 源, 
三 个 图 标 资 源 和 一 个exe 文 件 资源。

src1.rc:
S1 WAV wav1.Wav
C1 CURSOR cursor1.cur
C2 CURSOR cursor2.cur
I1 ICON icone1.ico
I2 ICON icone2.ico
I3 ICON icone3.ico
unzip EXEFILE pkunzip.exe

---- 你 可 以 将 写 好 的 rc 文 件 加 到 你 的 project项 目) 中。 你 也 
可 以 手 工 将 其 编 译 为 供 程 序直 接 使 用 的 二 进 制 资 源 文 件
(.res 文 件)。 在BCB3.0 中, 可 以 使 用 命 令 行: brcc32 src1.rc  src1.res 。 

---- 二: 资 源 的 使 用 

---- 下 面, 按 照 使 用 的 简 繁 程 度, 依 次 说 明 各类 资 源 的 使 用 
方 法。 需 要 说 明 的 是, 下 面 讲述 的 使 用 方 法, 在 别 的 编 译 环 
境 下(BC, VC 等)也 是 一 样 的。 

---- 1: 建 立 一 个 新 的 项 目 

---- 启 动 BCB3.0, 选 FILE- >new- >Application 建 立 一个 新 的 项 目。 

---- 在 project- >Add to Project 中, 加 入 写 好 的src1.rc 文 件。 当 然, 
那 些 声 音、 光 标、 图 标 文件 都 应 该 存 在。 

---- 这 时, 我 们 有 了 一 个 空 的 窗 体(Form)。 

---- 2: 能 够 利 用 windows API 函 数 直 接 访 问 的 资源 有:

图 标 LoadIcon()
光 标 LoadCursor()
加 速 表 LoadAccelerators()
位 图 LoadBitmap()
菜 单 LoadMenu()
字 符 串 LoadString()

---- 前 五 个 API 函 数 使 用 方 法 都 一 样, 带 两 个 参 数。 

---- 第 一 个 参 数 指 明 资 源 的 存 放 地 , 第 二 个 参 数 为 rc 文 件 
中 资 源 的 标 识。 

---- 字 符 串 LoadString 除 这 两 个 参 数 外, 还 有 两 个 参 数, 指 明 
字 符 串 缓 冲 区 的 地 址 和 大 小。 

---- 下 面 的 一 小 段 程 序 示 范 了 图 标 和 光 标 的 使 用。 

---- 在 Form 上 放 置 一 个 按 纽, 在 其 OnClick 事 件 中 加 入 以 下 代 码: 

void __fastcall TForm1::Button1Click(TObject *Sender) {
// 将光标形状改为自己定义的:
Screen- >Cursors[crDefault] = LoadCursor( HInstance, "C1");
// 将图标改为自己定义的:
Icon = new TIcon() ;
Icon- >Handle = LoadIcon(HInstance,"I1");
Application- >Icon = Icon ;
}

---- 其 中 的 HInstance 指 示 资 源 所 在 地 为 执 行 文 件。 编 译 执 行 
后, 点 击 该 按 纽, 光 标 和 图 标 都 会 换 成 新 的。 

---- 3: 能 够 通 过 windows API 使 用 的 资 源 

---- 对 于 声 音、 动 画 等 文 件, 可 以 使 用 windows API 函 数 播 放。 
但 是 不 象 上 面 几 种 资 源, 需 要 遵 循 一 定 的 步 骤。 如 下 所 示, 
依 次 调 用 FindResource, LoadResource, LockResource 函 数, 来 播 放 一 
个Wav 声 音 文 件。 

---- ( 当 然, 独 立 的 声 音 文 件 可 以 在 运 行 时 直 接 播 放。 我 们 
这 里 讨 论 的 是 将 wav 文 件 编 译 进 EXE 文 件 的 情 况) 

---- 在 Form 上 放 置 第 二 个 按 纽, 在 其 OnClick 事 件 中 加 入 以 下 
代 码: 

void __fastcall TForm1::Button2Click(TObject *Sender)
//定义资源块
char *wav_handle ;
//装入 Wav文件
HRSRC h = FindResource(HInstance,"S1","WAV");
HGLOBAL h1 = LoadResource(HInstance, h);
wav_handle = (char *)LockResource(h1);
//播放 Wav文件。由于Wav文件装载在内存中,
sndPlaySound函数要用 SND_MEMORY参数
sndPlaySound(wav_handle, SND_MEMORY | SND_SYNC);
}

---- 编 译 执 行 后, 点 击 该 按 纽, 会 播 放 一 次 声 音。 

---- 对 于 动 画 等 文 件, 使 用 方 式 类 似Wav 文 件。 ( BCB 提 供 了 
一 个TAnimate 控 件, 可 以 播 放 无 声 的Avi 文 件) 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -