RE: [PHP-WIN] How to copy from windows clipboard using PHP
| From: | Gonzalo MC | Date: | Wed, 07 Sep 2005 16:59:44 +0000 |
| Subject: | RE: [PHP-WIN] How to copy from windows clipboard using PHP | ||
| Groups: | php.windows | ||
| Request: | Send a blank email to php-windows+get-26306@lists.php.net to get a copy of this message | ||
Hi, It is possible to do it using php_Win32Api calls.
I'd rather attach you a php-gtk-general post with an example. It uses php4, php-gtk, and non-standard php_win32api... (Tom Rogers version with some plus functionality)
Hi all,
I've coded a GtkSheet copy&paste example for csv clipboard data from apps as Excel, it uses the code snippet posted by Tom Rogers for excel clipboard c&p.
Needs too the modified php_w32api from Tom, otherwise it won't work.
It shows too how to generate a mouse event using the api, and how to attach a mouse clicked popupmenu on the GtkSheet.
Regards,
Gonzalo.
<?php
if (!extension_loaded('gtk')) {
dl( 'php_gtk.' . PHP_SHLIB_SUFFIX);}
if( !extension_loaded('win32')) { dl( 'php_w32api.' . PHP_SHLIB_SUFFIX);
}
$win32api =& new win32;
$win32api->registerfunction("bool mouse_event (long Flags, long dx, long dy, long Data, long ExtraInfo ) From user32.dll");
$win32api->registerfunction("bool OpenClipboard
(
long hWndNewOwner
)
From user32.dll");
$win32api->registerfunction("bool CloseClipboard
(
)
From user32.dll");
$win32api->registerfunction("int EnumClipboardFormats
(
int format
)
From user32.dll");
$win32api->registerfunction("int GetClipboardFormatName
(
int format,
string &FormatName,
int cchMaxCount
)
From user32.dll");
$win32api->registerfunction("long GetClipboardData
(
int uFormat
)
From user32.dll");
$win32api->registerfunction("string GlobalLock
(
long hMem
)
From kernel32.dll");
$win32api->registerfunction("bool GlobalUnlock
(
long hMem
)
From kernel32.dll");
$win32api->registerfunction("bool EmptyClipboard
(
)
From user32.dll");
$win32api->registerfunction("int RegisterClipboardFormat
(
string &Format
)
From user32.dll");
$win32api->registerfunction("long SetClipboardData
(
int uFormat,
long hMem
)
From user32.dll");
$win32api->registerfunction("long GlobalAlloc
(
int uFlags,
long Bytes
)
From kernel32.dll");
$win32api->registerfunction("long lstrcpyn
(
long String1,
string &String2,
int iMaxLength
)
From kernel32.dll");
$win32api->registerfunction("long GlobalHandle
(
long pMem
)
From kernel32.dll");
define('GPTR',0x0040); //allocate memory and zero fill it. // Create the window:
$w = &new GtkWindow;
$w->set_title('Testing the GtkSheet');
$w->connect('destroy', create_function('','Gtk::main_quit();'));
$w->set_position(GTK_WIN_POS_CENTER); $w->set_default_size((gdk::screen_width()/1.5)-15, (gdk::screen_height()-20)-15); // Create the widgets: $box =& new GtkVBox(false, 5);$buttonbox =& new GtkHBox();
$scrollw =& new GtkScrolledWindow();
$sheet =& new GtkSheet(100, 22, "sheet");
$button1 =& new GtkButton("Reset");
$button2 =& new GtkButton("Clear");
// Callbacks:
$sheet->connect_after('traverse', 'sheet_traverse');
$sheet->connect_after('button-press-event', 'sheet_button_press');
//$sheet->connect('button-release-event', 'sheet_button_release');
$button1->connect('clicked', "SheetRenewData");
$button2->connect('clicked', "SheetClearData");
// Let's pack the widgets:$box->pack_start($scrollw, true, true, 0); $buttonbox->pack_start($button1, false, false, 0); $buttonbox->pack_start($button2, false, false, 0); $box->pack_start($buttonbox, false, false, 0);
// Configure the sheet://$sheet->set_selection_mode(0); $sheet->set_column_titles_height(21); $sheet->set_row_titles_width(25); $sheet->show_all();
// Insert data for the first time:$count = 0; SheetRenewData();
// Finally pack it to the window:$scrollw->add($sheet); $w->add($box);
$w->show_all();
Gtk::main();
function SheetClearData() {
global $count, $sheet;
for($row = 0; $row<=100; $row++) {
// Lets adjust the row height for the first time:
if ($count == 0) {
$sheet->set_row_height($row,21);
}
$sheet->freeze(); // Using freeze & thaw speeds up a lot this process.
for ($col = 0; $col<=22; $col++) {
// Set the sheet cell data:
$sheet->set_cell($row, $col, 1, "");
// Lets adjust column width for the first time:
if (($row == 0) && ($count == 0)){
$sheet->set_column_width($col, 50);
}
if ($count == 0)
$sheet->row_set_sensitivity($row, false);
}
$sheet->thaw();
}
//$sheet->rows_labels_set_visibility(false);
$sheet->show_all();
// Keep track of reset count:
$count++;
}
function SheetRenewData() {
global $count, $sheet;
for($row = 0; $row<=100; $row++) {
// Lets adjust the row height for the first time:
if ($count == 0) {
$sheet->set_row_height($row,21);
}
$sheet->freeze(); // Using freeze & thaw speeds up a lot this process.
for ($col = 0; $col<=22; $col++) {
// Set the sheet cell data:
$sheet->set_cell($row, $col, 1, "$count-$row");
// Lets adjust column width for the first time:
if (($row == 0) && ($count == 0)){
$sheet->set_column_width($col, 50);
}
if ($count == 0)
$sheet->row_set_sensitivity($row, false);
}
$sheet->thaw();
}
//$sheet->rows_labels_set_visibility(false);
$sheet->show_all();
// Keep track of reset count:
$count++;
}
// Called when leaving one cell in a sheet and going to the nextfunction sheet_traverse($sheet,$row,$col,$row_next,$col_next) {
global $sheet_active_row, $sheet_active_col;
$sheet_active_row = $row_next;
$sheet_active_col = $col_next;
}
function sheet_button_release(&$sheet, $event) {
}
function sheet_button_press(&$sheet, $event, $clicked=false) {
global $sheet_active_row, $sheet_active_col;
global $sheet_origin_row, $sheet_origin_col;
global $sheet_destiny_row, $sheet_destiny_col;
global $win32api;
global $sheet_drag_start;
global $sheet_drag_mtim;
global $sheet_dont_update;
global $sheet_selection_array;
if ($event->button == 1) {
// clicked?
if ($sheet_dont_update == false) {
$sheet_origin_row = $sheet_active_row;
$sheet_origin_col = $sheet_active_col;
}
return;
}
// Right Button pressed?
if ($event->button == 3) {
// Let's generate a left button press to activate the cell under cursor,
// and add timeout to run this function again but $clicked = true
// We need to activate the cell as the sheet doesn't do anything on right button press...
if (!$clicked) {
$sheet_dont_update = true;
$win32api->mouse_event(0x0002, 0, 0, 0, 0); // Left down
$win32api->mouse_event(0x0004, 0, 0, 0, 0); // Left up
gtk::timeout_add(50, 'sheet_button_press', &$sheet, &$event, true);
return;
}
$sheet_dont_update = false;
// Get destiny cell, if dragged selection it wont be the same row-cell than in origin
$sheet_destiny_row = $sheet_active_row;
$sheet_destiny_col = $sheet_active_col;
unset($sheet_selection_array);
// Do we have different origin <> destiny cells? let's 'traverse' the sheet and get the content: if (($sheet_origin_row != $sheet_destiny_row) || ($sheet_origin_col != $sheet_destiny_col)) {
// Check if reverse selection...
if ($sheet_origin_row > $sheet_destiny_row) {
$tmp = $sheet_origin_row;
$sheet_origin_row = $sheet_destiny_row;
$sheet_destiny_row = $tmp;
}
if ($sheet_origin_col > $sheet_destiny_col) {
$tmp = $sheet_origin_col;
$sheet_origin_col = $sheet_destiny_col;
$sheet_destiny_col = $tmp;
}
unset($tmpA);
for ($row = $sheet_origin_row; $row <= $sheet_destiny_row; $row++) {
unset($tmpB);
for ($col = $sheet_origin_col; $col <= $sheet_destiny_col; $col++) {
if (!isset($tmpB))
$tmpB = $sheet->cell_get_text($row,$col);
else
$tmpB = $tmpB.";".$sheet->cell_get_text($row,$col);
}
// Add tmp array
$tmpA[] = $tmpB;
}
// Add data to array:
$sheet_selection_array = $tmpA;
} else {
// Only a cell its been selected?
$sheet_selection_array[0] = $sheet->cell_get_text($sheet_active_row,$sheet_active_col); }
// Let's create a popup menu:
// Create GtkMenu and GtkMenuItems...
$menu=&new GtkMenu();
$color=&new GdkColor('#000000');
$color1=&new GdkColor('blue');
// First option: 'Copy'
$sel=&new GtkMenuItem();
$label1=&new GtkLabel('Copy');
$hbox=&new GtkHBox();
$hbox->pack_start($label1,true,false);
$sel->add($hbox);
//
$sel->connect_object('activate','sheet_popupmenu_copy', &$sheet, $sheet_selection_array);
$menu->append($sel);
// 'Paste'
$sel2=&new GtkMenuItem();
$label1=&new GtkLabel('Paste');
$hbox=&new GtkHBox();
$hbox->pack_start($label1,true,false);
$sel2->add($hbox);
//
$sel2->connect_object('activate','sheet_popupmenu_paste', &$sheet, $sheet_active_row, $sheet_active_col);
$menu->append($sel2);
$menu->show_all();
$menu->popup(null,null,null,1,$event->time);
//
}
}
function sheet_popupmenu_copy( &$sheet, $selection_data){
global $win32api;
$NameSize = 128;
reset($selection_data);
for($row = 0; $row <= count($selection_data); $row++) {
if (!isset($tmp))
$tmp = $selection_data[$row];
else
$tmp = $tmp."\r\n".$selection_data[$row];
}
$data = $tmp;
// CLIPBOARD CSV TYPE READING FROM EXCEL/WORD...
// get a clipboard id
$id = $win32api->OpenClipboard('');
if($id){
$Format = 'Clipboard CSV Data';
$ok = false;
$fn = $win32api->EnumClipboardFormats(0);
do {
$name = str_repeat("\0", $NameSize); //zero the name holder
$result = $win32api->GetClipboardFormatName($fn,$name,$NameSize);
if(preg_match('/CSV/i',$name)){
$ok = true;
break;
}
} while ($fn = $win32api->EnumClipboardFormats($fn));
$win32api->CloseClipboard();
$register = false;
if ($ok == false) {
$register = true;
}
$id = $win32api->OpenClipboard($name);
$win32api->EmptyClipboard(); // graw ownership if ($register)
$fn = $win32api->RegisterClipboardFormat($Format);
$dest = $win32api->GlobalAlloc(GPTR, strlen($data)+1);
$handle = $win32api->GlobalHandle(&$dest);
$win32api->GlobalLock($handle);
$ndest = $win32api->lstrcpyn($dest, $data, strlen($data)+1);
$win32api->GlobalUnlock($handle);
$win32api->SetClipboardData($fn, $handle);
$win32api->CloseClipboard();
}
}
function sheet_popupmenu_paste( &$sheet, $actual_row, $actual_col)
{
global $win32api;
$NameSize = 128;
// CLIPBOARD CSV TYPE READING FROM EXCEL/WORD...
// get a clipboard id
$id = $win32api->OpenClipboard('');
if($id){
$fn = $win32api->EnumClipboardFormats(0);
do {
$name = str_repeat("\0", $NameSize); //zero the name holder
$result = $win32api->GetClipboardFormatName($fn,$name,$NameSize);
if(preg_match('/CSV/i',$name)){
$data_handle = $win32api->GetClipboardData($fn);
if($data_handle){
$text = trim($win32api->GlobalLock($data_handle));
$rows = explode("\r\n",$text);
foreach($rows as $key=>$row){
$rows[$key] = explode(',',$row); //add columns
}
$win32api->GlobalUnlock($data_handle);
}
break;
}
//echo "Fn $fn $name\n";
} while ($fn = $win32api->EnumClipboardFormats($fn));
$win32api->CloseClipboard();
// Put data into sheet:
if (isset($rows)) {
reset($rows);
$sheet->freeze(); // Using freeze & thaw speeds up a lot this process.
for($row = 0; $row < count($rows); $row++) {
unset($row_data);
$tmp = $rows[$row];
$row_data = explode(';',$tmp[0]);
for($col = 0; $col < count($row_data); $col++) {
$cell_data = $row_data[$col];
$sheet->set_cell($row + $actual_row, $col + $actual_col, 1, $cell_data);
}
}
$sheet->thaw();
}
}
}
?>
Gonzalo Monzón escribió:
Hi Tom, I'm on WinXP sp2, I'll test later on another computer with Win2K and post the result. Probably this is the cause... Regards, Gonzalo. Tom Rogers escribió:-- PHP-GTK General Mailing List (http://gtk.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php Murray @ PlanetThoughtful escribió: >>Would anyone know how to copy an image/screen shot from the Windows's >>CLIPBOARD? I am trying to capture the clipboard content (image) populated >>by the use of the PrintScreen button on the standard keyboard and storing >>it in a MySQL database table field along with a key field. I then would >>be >>interested in fetching it later to display and/or print upon users' >>request. >> >> >> >>Has anyone developed such capability before? >> >> > >Hi Tony, > >I'm not aware of PHP having any clipboard functionality, which makes sense >when you think about it, since it's ordinarily run on the server, rather >than on the client, and while it does have CLI capabilities, these don't >appear to have been developed yet to cover specific desktop functions / >capabilities such as manipulating the clipboard. > >I know from experience that Python (and perhaps Perl?) is able to access the >clipboard, though, in case you want to investigate these. > >For myself, I use a freeware application called GrabCaptureScreen >(http://www.grabcapturescreen.com/) to perform screen captures and save to >filenames etc, and from there it should be a relatively simple process to >store the images in your db table. Having said which, I would look at the >possibility of simply storing the path/filename of the image in your table, >with the images physically stored as files on your harddrive, rather than as >binary objects in your db. > >Hope this helps, even if just a little. > >Much warmth, > >Murray >--- >"Lost in thought..." >http://www.planetthoughtful.org > > >Hi, Monday, July 11, 2005, 10:58:20 PM, you wrote: GM> Hi again Tom, GM> Sorry, yes, of course, I refer to your php_win32api.dll compiled against GM> php 4.3.6 and 4.3.11, not the standard ones... Your extension crashes GM> too for me with the example you wrote, that's why I sent my last GM> message... 'cause its strange to me someone sending an example wich does GM> not work, so its likely another problem... GM> Sorry for the misunderstanding.... GM> Regards GM> Gonzalo. GM> Tom Rogers escribió: I am using windows2k and it works ok never tested on xp or 98 what system are you testing on?