?
Solved

Determine size currently in the clipboard

Posted on 2011-10-28
6
Medium Priority
?
337 Views
Last Modified: 2012-05-12
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
Comment
Question by:Stef Merlijn
  • 3
  • 2
6 Comments
 
LVL 19

Accepted Solution

by:
Thommy earned 1332 total points
ID: 37047279
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
 

Author Comment

by:Stef Merlijn
ID: 37048743
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
 

Author Comment

by:Stef Merlijn
ID: 37048750
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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 19

Assisted Solution

by:Thommy
Thommy earned 1332 total points
ID: 37055315
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
 
LVL 24

Assisted Solution

by:jimyX
jimyX earned 668 total points
ID: 37074533
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
 

Author Closing Comment

by:Stef Merlijn
ID: 37074854
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

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Are you ready to place your question in front of subject-matter experts for more timely responses? With the release of Priority Question, Premium Members, Team Accounts and Qualified Experts can now identify the emergent level of their issue, signal…
With just a little bit of  SQL and VBA, many doors open to cool things like synchronize a list box to display data relevant to other information on a form.  If you have never written code or looked at an SQL statement before, no problem! ...  give i…
Suggested Courses

850 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question