全部分送上,帮忙的请进,难道不高的问题!!!(100分)

  • 主题发起人 主题发起人 killtimeer
  • 开始时间 开始时间
K

killtimeer

Unregistered / Unconfirmed
GUEST, unregistred user!
我想得到系统的全局原子的字符串,但好久也找不到相关的API,只有创建或找寻指定的字符串,没有获取全局原子的字符串,请高手指教一下!!!
 
什么是“全局原子”?
 
原子函数
GlobalFindAtom,GlobalAddAtom,GlobalDeleteAtom
我想得到全局原子表!!!高手进来
 
GlobalDeleteAtom(L); { 使用后释放 }
 
在项目文件里实现,示例如下:

program BestEIR;

uses
Forms,
Windows {函数beep;用于禁止运行程序多个实例},
MAIN in 'Source/Public/Main.pas' {fmMain},

const iAtom = 'IT-KING/MyEIR';{禁止程序多个实例:定义系统全局原子}

{$R *.RES}

begin
if GlobalFindAtom(iAtom)=0 then {禁止程序多个实例:查找系统全局原子}
begin {禁止程序多个实例}
GlobalAddAtom(iAtom);{禁止程序多个实例:向系统添加全局原子}
Application.Initialize;
Application.CreateForm(TfmMain, fmMain);
Application.Run;

GlobalDeleteAtom(GlobalFindAtom(iAtom));{禁止程序多个实例:删除系统全局原子}
end{禁止程序多个实例}
else {禁止程序多个实例}
begin
GlobalDeleteAtom(GlobalFindAtom(iAtom)); //先删除全局原子,防止程序出错后一直不能运行!
MessageBox(0,'程序已经运行!','Warning',mb_OK); {禁止程序多个实例}
end;
end.
 
高手们啊,我要的是得到系统的全部的全局原子表,
不是要自已创建的
或找寻一个自已指定的全局原子字符串!!!

高手进来啊!!!
 
写驱动可以解决,将全局原子表的地址空间射到你的应用程序地址空间,一般来说工作在第三层的应用程序是不能直接访问全局原子表的
 
不会吧!!!
 
给你一段C代码看看
/*
* Server-side atom management
*
* Copyright (C) 1999, 2000 Alexandre Julliard
* Copyright (C) 2000 Turchanov Sergei
*/

#include <assert.h>
#include <stdlib.h>
#include <stdio.h>

#include "assert.h"
#include "stdlib.h"
#include "stdio.h"

#define HASH_SIZE 37
#define MAX_ATOM_LEN 255
#define MAX_ATOMS 0x4000

struct atom_entry
{
struct atom_entry *next; /* hash table list */
struct atom_entry *prev; /* hash table list */
int atom; /* atom handle */
int count; /* reference count */
int hash; /* string hash */
WCHAR str[1]; /* atom string */
};

struct atom_table
{
struct object obj; /* object header */
int count; /* count of atom handles */
int last; /* last handle in-use */
struct atom_entry **handles; /* atom handles */
struct atom_entry *entries[HASH_SIZE]; /* hash table entries */
};


static void atom_table_dump( struct object *obj, int verbose );
static void atom_table_destroy( struct object *obj );

static const struct object_ops atom_table_ops =
{
sizeof(struct atom_table), /* size */
atom_table_dump, /* dump */
no_add_queue, /* add_queue */
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satified */
NULL, /* get_poll_events */
NULL, /* poll_event */
no_read_fd, /* get_read_fd */
no_write_fd, /* get_write_fd */
no_flush, /* flush */
no_get_file_info, /* get_file_info */
atom_table_destroy /* destroy */
};

static struct atom_table *global_table;


/* copy an atom name to a temporary area */
static const WCHAR *copy_name( const WCHAR *str )
{
static WCHAR buffer[MAX_ATOM_LEN+1];
WCHAR *p = buffer;

while (p < buffer + sizeof(buffer) - 1) if (!(*p++ = *str++)) break;
*p = 0;
return buffer;
}

/* create an atom table */
static struct atom_table *create_table(void)
{
struct atom_table *table;

if ((table = alloc_object( &atom_table_ops, -1 )))
{
table->count = 64;
table->last = -1;
memset( table->entries, 0, sizeof(table->entries) );
if ((table->handles = mem_alloc( sizeof(*table->handles) * table->count )))
return table;
release_object( table );
table = NULL;
}
return table;
}

/* retrieve an entry pointer from its atom */
static struct atom_entry *get_atom_entry( struct atom_table *table, int atom )
{
struct atom_entry *entry = NULL;
if (table && (atom >= 0) && (atom <= table->last)) entry = table->handles[atom];
if (!entry) set_error( STATUS_INVALID_HANDLE );
return entry;
}

/* add an atom entry in the table and return its handle */
static int add_atom_entry( struct atom_table *table, struct atom_entry *entry )
{
int i;
for (i = 0; i <= table->last; i++)
if (!table->handles) goto found;
if (i == table->count)
{
struct atom_entry **new_table = NULL;
int new_size = table->count + table->count / 2;
if (new_size > MAX_ATOMS) new_size = MAX_ATOMS;
if (new_size > table->count)
new_table = realloc( table->handles, sizeof(*table->handles) * new_size );
if (!new_table)
{
set_error( STATUS_NO_MEMORY );
return -1;
}
table->count = new_size;
table->handles = new_table;
}
table->last = i;
found:
table->handles = entry;
entry->atom = i;
return i;
}

/* compute the hash code for a string */
static int atom_hash( const WCHAR *str )
{
int i;
WCHAR hash = 0;
for (i = 0; str; i++) hash ^= towupper(str) + i;
return hash % HASH_SIZE;
}

/* dump an atom table */
static void atom_table_dump( struct object *obj, int verbose )
{
int i;
struct atom_table *table = (struct atom_table *)obj;
assert( obj->ops == &atom_table_ops );

fprintf( stderr, "Atom table size=%d/n", table->last + 1 );
if (!verbose) return;
for (i = 0; i <= table->last; i++)
{
struct atom_entry *entry = table->handles;
if (!entry) continue;
fprintf( stderr, " %5d: ref=%d hash=%d /"", i, entry->count, entry->hash );
dump_strW( entry->str, strlenW(entry->str), stderr, "/"/"");
fprintf( stderr, "/"/n" );
}
}

/* destroy the atom table */
static void atom_table_destroy( struct object *obj )
{
int i;
struct atom_table *table = (struct atom_table *)obj;
assert( obj->ops == &atom_table_ops );
for (i = 0; i <= table->last; i++) free( table->handles );
free( table->handles );
}

/* find an atom entry in its hash list */
static struct atom_entry *find_atom_entry( struct atom_table *table, const WCHAR *str, int hash )
{
struct atom_entry *entry = table->entries[hash];
while (entry)
{
if (!strcmpiW( entry->str, str )) break;
entry = entry->next;
}
return entry;
}

/* close the atom table; used on server exit */
void close_atom_table(void)
{
if (global_table) release_object( global_table );
}

/* add an atom to the table */
static int add_atom( struct atom_table *table, const WCHAR *str )
{
struct atom_entry *entry;
int hash = atom_hash( str );
int atom = -1;

if (!*str)
{
set_error( STATUS_OBJECT_NAME_INVALID );
return -1;
}
if ((entry = find_atom_entry( table, str, hash ))) /* exists already */
{
entry->count++;
return entry->atom;
}

if ((entry = mem_alloc( sizeof(*entry) + strlenW(str) * sizeof(WCHAR) )))
{
if ((atom = add_atom_entry( table, entry )) != -1)
{
entry->prev = NULL;
if ((entry->next = table->entries[hash])) entry->next->prev = entry;
table->entries[hash] = entry;
entry->count = 1;
entry->hash = hash;
strcpyW( entry->str, str );
}
else free( entry );
}
else set_error( STATUS_NO_MEMORY );
return atom;
}

/* delete an atom from the table */
static void delete_atom( struct atom_table *table, int atom )
{
struct atom_entry *entry = get_atom_entry( table, atom );
if (entry && !--entry->count)
{
if (entry->next) entry->next->prev = entry->prev;
if (entry->prev) entry->prev->next = entry->next;
else table->entries[entry->hash] = entry->next;
table->handles[atom] = NULL;
free( entry );
}
}

/* find an atom in the table */
static int find_atom( struct atom_table *table, const WCHAR *str )
{
struct atom_entry *entry;

if (table && ((entry = find_atom_entry( table, str, atom_hash(str) )))) return entry->atom;
if (!*str) set_error( STATUS_OBJECT_NAME_INVALID );
else set_error( STATUS_OBJECT_NAME_NOT_FOUND );
return -1;
}

/* get an atom name and refcount*/
static int get_atom_name( struct atom_table *table, int atom, WCHAR *str )
{
int count = -1;
struct atom_entry *entry = get_atom_entry( table, atom );
if (entry)
{
strcpyW( str, entry->str );
count = entry->count;
}
return count;
}

/* add a global atom */
DECL_HANDLER(add_atom)
{
if (!global_table) global_table = create_table();
if (global_table) req->atom = add_atom( global_table, copy_name( req->name ) );
}

/* delete a global atom */
DECL_HANDLER(delete_atom)
{
delete_atom( global_table, req->atom );
}

/* find a global atom */
DECL_HANDLER(find_atom)
{
req->atom = find_atom( global_table, copy_name( req->name ) );
}

/* get global atom name */
DECL_HANDLER(get_atom_name)
{
req->count = get_atom_name( global_table, req->atom, req->name );
}
 
这篇文章适合你:

DELPHI中使用WINDOWS系统原子
原子和原子表:
Win32系统中,为了实现信息共享,系统维护了一张全局原子表,用于保存字符串与之
对应的标志符的组合。应用程序将一个字符串放到原子表中,并接受系统返回的一个16位
的整数,这个整数被称为原子(ATOM),用于访问可变长度的字符串,而放到原子表保存
的字符串称为原子名称。
原子表分为全局(GLOBAL)原子表和局部(LOCAL)原子表,全局原子表可以被所
有的应用程序使用,当一个程序把字符串注册到原子表中以后,系统产生一个原子,原子是
一个唯一的整型ID,用来访问可变长度的字符串,Windows NT 和 Windows 98 的系统库
都在全局原子表中为已注册的系统信息和已注册的剪贴板格式创建原子。因为这些值是在进
程间共享的,所以,它们必须驻留在共享内存区,在 Windows 98 上原子值的数目为 1K,
在 Windows NT 上原子值的数目为 16K。因为原子的唯一性,通过查询全局原子表,任何
程序都可以用全局原子获得它所标志的字符串;与全局原子表相关的API函数有
GLOBALAddAtom,GLOBALDeleteAtom,GLOBALFINDATOM,GLOBALGetAtomNam;
局部原子表只能被创建这个原子表的应用程序使用。局部原子是把在应用程序中大量出
现的相同字符串放到系统原子表中,在结构中包含这些原子,这样就不必把每个字符串放到
结构中,一个字符串在内存中只出现一次,从而减少了占用的内存!与局部原子表相关的
API函数有ADDATOM,DELETEATOM,FINDATOM,GETATOMNAME;

本文用到的相关的API函数:
ATOM GlobalAddAtom( //将字符串添加到系统全局原子表中,该函数返回原子
LPCTSTR lpString
);
ATOM GlobalDeleteAtom( //从全局原子表中删除该原子
ATOM nAtom //ATOM为原子
);
ATOM GlobalFindAtom( //从全局原子表中查找字符串
LPCTSTR lpString //要查找的字符名称
);
UINT GlobalGetAtomName( //在消息过程中获得字符串
ATOM nAtom, //将要查找的原子
LPTSTR lpBuffer, //要保存到的字符变量
int nSize //长度
);
FindWindow(       //返回一个窗口的句柄
lpClassName: PChar; //类名称 , 就是这个 Window 在系统中注册的名字。
lpWindowName: PChar //窗口名称,就是这个 Window Window 可显示出來的Text 。
): HWND;

BOOL PostMessage(   //向指定窗口发送消息
HWND hWnd, //目的窗口的句柄
UINT Msg, //要发送的消息
WPARAM wParam,, //第一个消息的参数
LPARAM lParam // 第二个消息的参数
);
原子表在系统编程中的应用:
一、保证程序只运行一次(使用全局原子表)
程序思路:在每次程序运行之前,查询系统全局原子表,看是否有指定的字符串存在,要用
到GLOBALFINDATOM,如果GLOBALFINDATOM返回不为0,说明程序副本已经运行,
提示错误信息,并关闭程序;如果返回为0,说明程序副本没有运行,添加指定字符串到系
统全局原子表(GLOBALADDATOM,并运行程序;在软件关闭之前,要将指定的字符串在
系统原子表中删除(GLOBALDELETEATOM);
程序源码如下:
procedure TForm1.FormCreate(Sender: TObject);
const atom_id='这里存放你的程序标示';
//注意这个地方的ATOM_id要与FORMCLOSE的ATOM_id要一致才可以
var
testatom:integer;
begin
testatom:=globalfindatom(pchar(atom_id));
if testatom=0 then
begin
testatom:=globaladdatom(pchar(atom_id));
end
else
begin
showmessage('程序副本已经运行,按确定后终止该程序!');
application.Terminate;
end;

end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
const atom_id='这里存放你的程序标示';
var
testatom:integer;
begin
testatom:=globalfindatom(pchar(atom_id));
globaldeleteatom(testatom);
end;

二、 在程序之间传输字符串数据(使用全局原子表)
在实际应用中,我们经常需要多个程序相互配合来完成某些特定功能。例如两个应用程序间
的同步、互斥;应用程序在起第二份实例时的参数自动传递…。要实现这些功能,就必须能
实现程序间的数据传递。
思路:
1、 先定义自定义的消息,WM_ATOMDATA;
2、 A程序中要用到API函数获得B程序的句柄,如HN;
3、 A程序将要传输的字符串加到系统全局原子表中GLOBALADDATOM;
4、 用POSTMESSAGE(HN,WM_ATOMDATA,ATOM,0)将刚添加的全局原子投递到
B窗口,其中WM_ATOMDATA是用户自定义的消息。
5、 B程序中处理WM_ATOMDATA消息,来得到A程序中传输过来的原子
6、 用GLOBALGETATOMNAME(ATOM(A程序传输的原子),BUFFER(存放原子名称),
256(长度,最多为256个字符));来接受原子;

程序代码如下:
(1)、发送端源程序如下:
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
CONST WM_Atomdata=WM_USER+200;
//自定义的消息,注意要与接受程序的WM_ATOMDATA一致;
type
Treceive_atom = class(TForm)
Myedit: TEdit;
Button1: TButton;
procedure Button1Click(Sender: TObject);

private
{ Private declarations }
public
{ Public declarations }
end;

var
receive_atom: Treceive_atom;

implementation

{$R *.DFM}
procedure Treceive_atom.Button1Click(Sender: TObject);
const atom_id='这里存放你的程序间传输的字符串';
var
Hn:HWND;
test_atom:integer;
begin
test_atom:=globaladdatom(pchar(atom_id));  //将字符串添加到全局原子表;
hn:=findwindow('TSend_atom','Send_atom');  //查找目的窗口的句柄;
postmessage(hn, WM_Atomdata,test_atom,0); //想目的窗口发送消息;
end;
procedure Treceive_atom.FormClose(Sender: TObject;
var Action: TCloseAction);
const atom_id='这里存放你的程序间传输的字符串';  
//这个与上面的第一一定要一致才可以!!!
var
test_atom:integer;
begin
test_atom:=globalfindatom(pchar(atom_id)); //在全局原子表中查找指定字符串;
globaldeleteatom(test_atom);       //删除程序一开始建立的原子;
end;
end.
(2)、接受端源程序:
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
CONST WM_Atomdata=WM_USER+200; 
//自定义的消息,注意要与发送程序的WM_ATOMDATA一致;
type
Tsend_atom = class(TForm)
Edit1: TEdit;
procedure proc(var message:tmessage);message WM_ATOMDATA;
//定义用自定义消息的处理函数
private
{ Private declarations }
public
{ Public declarations }
end;

var
send_atom: Tsend_atom;

implementation

{$R *.DFM}

procedure tsend_atom.proc(var message:tmessage);
var
myatom:integer;
buffer:pchar;
leng:integer;
begin
showmessage('已经接受到发送程序发送的消息了!'); //显示框提示受到消息;
myatom:=message.WParam; //取得原子
getmem(buffer,256);       
leng:=globalgetatomname(myatom,buffer,256);
//查找全局原子表,并把查找到的字符串放到BUFFER中
edit1.text:=buffer;
 //在edit1中显示字符串
freemem(buffer);
 //释放内存
end;

end.
测试步骤:
1、 运行发送程序;
2、 运行接受程序;
3、 在接受程序运行完毕后,按下发送程序的BUTTON1;
4、 看看接受程序中的EDIT1里面是否为'这里存放你的程序间传输的字符串'。
注意:
1、 原子名称最长为255个字符,所以在程序间传输的字符串最长长度为256!
2、将某一个字符串加入 全局原子表后,一定要有相对应的删除动作,不然即使应用程序已
经結束了,該 原子还是回保留在系统中,直到删除动作发生或则关机。

//==========================
作者联系地址:
以上程序均在DELPHI5+WIN 2000下调试通过,如果大家有什么意见或有什么更好的想法,
请EMAIL到jiaorg@ah163.com。
 
看看我这个:
if GlobalGetAtomName (Msg.LParam, szBuffer, 255) = 0 then
StrCopy ( szBuffer, '错误提示: 该原子没有发现!' );

参数说明自己找找吧。我用过的代码。
 
我想得到系统的全局原子的字符串(全部)!!!
请高手指教一下!!!
 
查了一下 API 方面的书籍,似乎没有获取全局原子列表的 API。估计你的要求很难实现。
 
有什么方法可以得到其它程序创建的原子?
顶一下!!!!
 
发给你了!!!! 在合子找到的
 
接受答案了.
 
后退
顶部