• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 363
  • Last Modified:

Determine size currently in the clipboard

Hi,

In a E-mail editor an user can paste a image from clipboard.
I want to check if the size isn't too big for mailing-purposes (let's say max 1 MB).

Is there a way to determine to size of the corrent clipboard?
Also I might be that the clipboard contains more than just one image or also include text. In that case it is sufficient to determine to full size of the clipboard.
0
Stef Merlijn
Asked:
Stef Merlijn
  • 3
  • 2
3 Solutions
 
ThommyCommented:
There is already an EE question addressing your problem...

How can I determine the size of the current clipboard ?
http://www.experts-exchange.com/Programming/Languages/Pascal/Delphi/Q_22099289.html
0
 
Stef MerlijnDeveloperAuthor Commented:
Hi,

I've tested the threaded approach (the one that got accepted).

I opened MS Word and pasted three images into it.
The total size of the images is about 3 Mb.
Also I added a few lines of tekst.
Now I did CTRL + A (copy all to clipboard.

When I run the code, it returns 12,7 MB.
Is this correct? Does the clipboard add a considerable amount of stuff so size increases that much?
0
 
Stef MerlijnDeveloperAuthor Commented:
Here is the full code as I currently use it.
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
     Button1 : TButton;
     procedure Button1Click(Sender: TObject);
  private
     // Private declarations
  protected
     // Protected declarations
  public
     // Public declarations
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

function ThreadClipboardSize(lParam: Pointer): DWORD; stdcall;
var  dwTimeout:     Cardinal;
     dwSize:        DWORD;
     dwFmt:         UINT;
     hClip:         THandle;
begin
  // Get timeout value
  dwTimeout := DWORD(lParam);
  // Set size accumulator
  dwSize := 0;
  // Get current tick count and append the timeout to give us an endpoint
  if (dwTimeout > 0) then
    Inc(dwTimeout, GetTickCount);
  // Open clipboard passing in null (open against this task)
  if OpenClipboard(0) then
  begin
    // Resource protection
    try
      // Enumerate the clipboard items
      dwFmt := EnumClipboardFormats(0);
      // While format
      while (dwFmt > 0) do
      begin
        // Check for timeout
        if not(dwTimeout = 0) and (GetTickCount >= dwTimeout) then
          break;
        // Get clipboard data
        hClip := GetClipboardData(dwFmt);
        // Check handle
        if (hClip > 0) then
          Inc(dwSize, GlobalSize(hClip));
        // Enumerate next
        dwFmt := EnumClipboardFormats(dwFmt);
      end;
    finally
      // Close the clipboard
      CloseClipboard;
    end;
  end;
  // Check for timeout
  if not(dwTimeout = 0) and (GetTickCount >= dwTimeout) then
    // Timed out getting the clipboard size, return zero size
    result := 0
  else
    // Return size
    result := dwSize;
end;

function GetClipboardSizeTimeout(Timeout: Cardinal = INFINITE): Cardinal;
var  hThread:       THandle;
     dwThread:      DWORD;
     dwError:       Integer;
begin
  // Set default error code
  dwError := ERROR_TIMEOUT;
  // Resource protection
  try
    // If INFINTE is passed in as timeout, don't even bother with creating the thread
    if (Timeout = INFINITE) then
    begin
      // Call the routine on the main thread
      result := ThreadClipboardSize(nil);
      // Set error code
      dwError := ERROR_SUCCESS;
    end else
    // Check for zero timeout
    if (Timeout = 0) then
      // Don't do anything
      result := 0
    else
    begin
      // Create the thread
      hThread := CreateThread(nil, 0, @ThreadClipboardSize, Pointer(Timeout), 0, dwThread);
      // Check handle
      if (hThread = 0) then
        // Return zero, failed to create thread
        result := 0
      else
      begin
        // Resource protection
        try
          // Wait for thread to be signaled (finished) or timeout to occur
          if (WaitForSingleObject(hThread, Timeout)  = WAIT_OBJECT_0) then
          begin
            // Thread is done, get thread exit code
            if GetExitCodeThread(hThread, dwThread) then
            begin
              // Return the size
              result := dwThread;
              // Update the error code
              dwError := ERROR_SUCCESS;
            end else
              // Failed to get exit code
              result := 0;
          end else
            // Timeout or error occurred, return zero size either way
            result := 0;
        finally
          // Close thread handle
          if not(hThread = 0) then
            CloseHandle(hThread);
        end;
      end;
    end;
  finally
    // Set the error code for GetLastError
    SetLastError(dwError);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var dwMark  : Cardinal;
    dwSize  : Cardinal;
    dwError : Integer;
    vGrootte : String;
begin
  // Save tick count
  dwMark := GetTickCount;
  try
    // Get clipboard size, passing 1000 (1 second) as the timeout limit
    dwSize := GetClipboardSizeTimeout(3000);
    // Save the last error code (if you want to check for a "timed out" state)
    dwError := GetLastError;
  finally
    // Get the total time spent, just to verify that the timeout value was honored
    dwMark := GetTickCount - dwMark;
  end;
  // Check error code
  if (dwError = ERROR_TIMEOUT) then
    // Display timeout info
    ShowMessage(Format('(%d ms) Timed out getting the clipboard data', [dwMark]))
  else
    // Display clipboard size
//    ShowMessage(Format('(%d ms) Clipboard data size is: %d bytes', [dwMark, dwSize]));
//    ShowMessage(Format('Clipboard data size is: %d bytes', [dwSize]));
  begin
    case dwSize of
      0..1023             : vGrootte := format('%d bytes',[dwSize]);         //        tot   1 Kb, return 'x bytes'
      1024..10239         : vGrootte := format('%.1f KB',[dwSize/1024]);     //   1 Kb tot  10 Kb, return  'x.x KB'
      10240..102399       : vGrootte := format('%.1f KB',[dwSize/1024]);     //  10 Kb tot 100 Kb, return  'x.x KB'
      102400..1048575     : vGrootte := format('%.1f KB',[dwSize/1024]);     // 100 Kb tot   1 Mb, return  'x.x KB'
      1048576..1073741823 : vGrootte := format('%.1f MB',[dwSize/1048576]);  //   1 Mb tot   1 Gb, return  'x.x MB'
    else
      vGrootte := format('%.2f GB',[dwSize/1073741824]);                     //     meer dan 1 Gb, return 'x.xx GB'
    end;
    ShowMessage(Format('Clipboard size is %s', [vGrootte]));
  end;
end;

end.

Open in new window

0
Cloud Class® Course: Certified Penetration Testing

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

 
ThommyCommented:
You can verify the memory, that is utilized by the clipboard, with the tool below:

ClipSize – Clear Clipboard Data And Monitor Size Of Clipboard
http://www.addictivetips.com/windows-tips/clear-clipboard-data-and-monitor-size-of-clipboard-clipsize/
0
 
jimyXCommented:
Delphiwizard,
You can follow the Lotus Notes method, which you can draft your message with any size but the calculation of the total size is done just before sending, which means you can attach files and it will not inform you yet until you try to send, if the size is more than the allowed size per message, it prompts with the max size of the message that it could be sent.
0
 
Stef MerlijnDeveloperAuthor Commented:
The supplied code works, though it isn't given a value with which I can work within my application.
Therefore I decided to determine the size at the moment the E-mail is being sent (as jimyX suggested).
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: CompTIA Healthcare IT Tech

This course will help prep you to earn the CompTIA Healthcare IT Technician certification showing that you have the knowledge and skills needed to succeed in installing, managing, and troubleshooting IT systems in medical and clinical settings.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now