RE: How to copy from windows clipboard using PHP

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 next
  function 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ó:

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?



--
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


--
PHP Windows Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


[Index of Archives]     [PHP Home]     [PHP Users]     [PHP Database Programming]     [PHP Install]     [Kernel Newbies]     [Yosemite Forum]     [PHP Books]

  Powered by Linux