1

I have a method like this

public static LinkedList<Object> getListObjectWithConditionInXMLFile(String className){
       LinkedList<Object> lstObj = new LinkedList<Object>();
       if(className.equals("Customer")){
            //read Data from XML File
            Customer customer = ...;
            lstObj.add(customer);
       }
       ....
       return lstObj;
}

after that i call this method and want to cast :

LinkedList<Customer> lstCustomer = (LinkedList<Customer>()) getListObjectWithConditionInXMLFile("Customer");

But it cannot cast. How can i cast from LinkedList to LinkedList ? Pls help me ! thanks so much !


Where I can get information about internal working of clipboard?

I would like to read some articles or books about how works windows clipboard inside, but I can't find at least one article that was deeper than standard API references or examples of using .

I'm working with windows clipboard over standart winapi and I obtain some strange results.

Case 1: I write to clipboard some unicode string and remember address of that string. Then I close clipboard, and repeat following procedure: open clipboard, get address of my unicode string, close clipboard.

I think that I must receive same addresses of clipboard content but it isn't. Why?

        //1.) Copying string to clipboard
        if (WinAPI.OpenClipboard(owner))
        {
            WinAPI.EmptyClipboard();

            IntPtr exampleStringPtr = Marshal.StringToHGlobalUni("Example");

            Console.WriteLine("setting address: {0}", exampleStringPtr.ToInt32());

            WinAPI.SetClipboardData(WinAPI.CF_UNICODETEXT, exampleStringPtr);

            WinAPI.CloseClipboard();
        }

        //2.) Getting string from clipboard
        for (int i = 0; i < 100; i++ )
            if (WinAPI.OpenClipboard(owner))
            {
                IntPtr exampleStringPtr = WinAPI.GetClipboardData(WinAPI.CF_UNICODETEXT);

                Console.WriteLine("getting address: {0}", exampleStringPtr.ToInt32());

                WinAPI.GlobalLock(exampleStringPtr);

                var s = Marshal.PtrToStringUni(exampleStringPtr);

                WinAPI.GlobalUnlock(exampleStringPtr);
                WinAPI.CloseClipboard();
            }

case 2: I write to clipboard some string, close clipboard, change string (in unmanaged memory) and again open clipboard and read this string. To my surprise, I obtain SAME string address and my UNCHANGED string.

        //1.) Copying string to clipboard
        if (WinAPI.OpenClipboard(owner))
        {
            WinAPI.EmptyClipboard();

            IntPtr exampleStringPtr = Marshal.StringToHGlobalUni("Loooooooooooonng String Example");

            Console.WriteLine("setting address: {0}", exampleStringPtr.ToInt32());

            WinAPI.SetClipboardData(WinAPI.CF_UNICODETEXT, exampleStringPtr);

            WinAPI.CloseClipboard();

            //2.) Change string - replace first 10 characters on one any symbol 
            for (int i = 0; i < 10; i++)
            {
                Marshal.WriteByte(exampleStringPtr + i, 50);
            }

            //3.) Obtain string and make sure that string was changed
            Console.WriteLine("changed string: {0}", Marshal.PtrToStringUni(exampleStringPtr));
        }


            //2.) Getting string from clipboard
            for (int i = 0; i < 100; i++)
                if (WinAPI.OpenClipboard(owner))
                {
                    IntPtr exampleStringPtr = WinAPI.GetClipboardData(WinAPI.CF_UNICODETEXT);

                    Console.WriteLine("getting address: {0}", exampleStringPtr.ToInt32());

                    WinAPI.GlobalLock(exampleStringPtr);

                    var s = Marshal.PtrToStringUni(exampleStringPtr);

                    Console.WriteLine("obtained string: {0}", s);

                    WinAPI.CloseClipboard();
                }

Now I'm thinking that clipboard copy all memory block in SetClipboardData to other memory and source block can be copied several times. I can't understand, why I can't free my unmanaged memory for string immediately after SetClipboardData execution?

I have many questions and I think that some literature will make it clear

UPDATE:

to Raymond Chen, Jonathan Potter, Eric Brown: thank's for your answers, but I edited my second test that it would be more correct and now it shows following: I change source string BEFORE clipboard was closed and I may think it is valid operation and it removes answers that I make it after clipboard was closed. Then I get this string and results shows that is changed, then I get this string by invoking GetClipboardData and results shows that string was changed and pointer is same. Then I close clipboard open it again and read string again. What I obtain now? string address is same as address of source string but string is UNCHANGED. Here's this code:

        //1.) Copying string to clipboard
        if (WinAPI.OpenClipboard(owner))
        {
            WinAPI.EmptyClipboard();

            IntPtr exampleStringPtr = Marshal.StringToHGlobalUni("Loooooooooooonng String Example");

            Console.WriteLine("setting address: {0}", exampleStringPtr.ToInt32());

            WinAPI.SetClipboardData(WinAPI.CF_UNICODETEXT, exampleStringPtr);

            //2.) Change string while clipboard isn't closed - replace first 10 characters on one any symbol 
            for (int i = 0; i < 10; i++)
            {
                Marshal.WriteByte(exampleStringPtr + i, 50);
            }

            //3.) Obtain string and make sure that string was changed
            Console.WriteLine("changed string: {0}", Marshal.PtrToStringUni(exampleStringPtr));

            //4.) Get this string from clipboard and make sure that clipboard was changed
            exampleStringPtr = WinAPI.GetClipboardData(WinAPI.CF_UNICODETEXT);

            Console.WriteLine("getting address of changed string: {0}", exampleStringPtr.ToInt32());

            var lockedPtr = WinAPI.GlobalLock(exampleStringPtr);

            var s = Marshal.PtrToStringUni(exampleStringPtr);
            WinAPI.GlobalUnlock(lockedPtr);

            Console.WriteLine("obtained string: {0}", s);

            WinAPI.CloseClipboard();

        }
            Console.WriteLine("\n-------Close and open clipboard------------------\n");

            //5.) Getting string from clipboard
            for (int i = 0; i < 100; i++)
                if (WinAPI.OpenClipboard(owner))
                {
                    IntPtr exampleStringPtr = WinAPI.GetClipboardData(WinAPI.CF_UNICODETEXT);

                    Console.WriteLine("getting address: {0}", exampleStringPtr.ToInt32());

                    var lockedPtr = WinAPI.GlobalLock(exampleStringPtr);

                    var s = Marshal.PtrToStringUni(lockedPtr);

                    WinAPI.GlobalUnlock(lockedPtr);

                    Console.WriteLine("obtained string: {0}", s);

                    WinAPI.CloseClipboard();
                }

I run program, paused it and analyzied memory by WinDbg. Then I make screenshot of results and provide for it you. http://postimg.org/image/are6um7yv/ So, my tests and screenshot shows that:

1.) We have several copies of one source object in memory 2.) If I change source memory given to SetClipboardData invoke before closing clipboard, after opening it again clipboard restore source object even on source address.

Isn't is? Can anyone explain, whether these clauses are true or not?

UPDATE 2: Ok.. I was rewriting my third test on C++. it's here:

#include "stdafx.h"
#include "windows.h"
#include "conio.h"

int main()
{
HWND owner = GetConsoleWindow();

//1.) Copying string to clipboard
if (OpenClipboard(owner))
{
    EmptyClipboard();

    //WCHAR *str = L"Loooong string example";
    char *str = "Loooooooong string Example";

    int cch = strlen(str);

    char* strptr = (char*)GlobalAlloc(GMEM_MOVEABLE, (cch + 1));

    printf("setting (segment??) address: %X \n", strptr);

    LPVOID lockedPtr = GlobalLock(strptr);
    printf("locked setting address: %X \n", lockedPtr);

    // copy
    memcpy(lockedPtr, str, cch);

    GlobalUnlock(strptr);

    // set to clipboard
    SetClipboardData(CF_TEXT, strptr);

    //2.) Change string while clipboard isn't closed - replace first 10 characters on one any symbol 
    lockedPtr = GlobalLock(strptr);
    for (int i = 0; i < 10; i++)
    {
        ((char*)lockedPtr)[i] = 50;
    }
    GlobalUnlock(strptr);

    //3.) Obtain string and make sure that string was changed
    lockedPtr = GlobalLock(strptr);
    printf("changed string: %s \n", lockedPtr);
    GlobalUnlock(strptr);

    //4.) Get this string from clipboard and make sure that clipboard was changed
    strptr = (char*)GetClipboardData(CF_TEXT);

    printf("getting address: %X \n", strptr);

    lockedPtr = GlobalLock(strptr);

    printf("locked getting address: %X \n", lockedPtr);

    printf("obtained string: %s \n", (char*)lockedPtr );

    GlobalUnlock(strptr);

    CloseClipboard();

}

printf("\n-------Close and open clipboard------------------\n");

//5.) Getting string from clipboard
for (int i = 0; i < 10; i++)
{
    //Sleep(1000);
    if (OpenClipboard(owner))
    {
        HANDLE exampleStringPtr = GetClipboardData(CF_TEXT);

        printf("getting address: %X \n", exampleStringPtr);

        char* lockedPtr = (char*)GlobalLock(exampleStringPtr);

        printf("locked getting address: %X \n", lockedPtr);
        printf("obtained string: %s \n", lockedPtr);

        GlobalUnlock(exampleStringPtr);

        CloseClipboard();
    }
}

getch();
return 0;
} 

Really, now when I invoke GetClipboardData then I obtain the same pointer to the data all the time. But sometimes it was different from locked pointer of first string that I putted to the clipboard.

But although I'm writing this test on C++, I still have same effect I was writeing early.

If I change source memory block after invoking SetClipboardData and then try to invoke GetClipboardData, I obtain my changed memory block. But when I close this clipboard and then open it again, my changed memory block was overriten with some info, I don't know, and when I invoke GetClipboardData, that memory block was restored to initial state as if I didn't change it.

From where clipboard "knows" how to restore this block if it hasn't its copies and I changed source block?

I recorded little screencast that shows in what moment memory restored http://screencast.com/t/5t3wc9LS

4

2 に答える 2

0

新しいリストを作成し、キャストされたオブジェクトを Customer の新しいリンク リストに追加する必要があります。

LinkedList<Customer> custList = new LinkedList<>();
for(Object obj: getListObjectWithConditionInXMLFile("Customer")) {
   custList.add((Customer)obj));
}

または、「Boris the Spider」のコメントで言及されているように、可能であればジェネリックを使用することをお勧めします。

 public static <T> LinkedList<T> getListObjectWithConditionInXMLFile(Class<T> requiredClass)

定義は、「micha」によって次のように指定できます。

public static <T> LinkedList<T> getListObjectWithConditionInXMLFile(Class<T> requiredClass){
       LinkedList<T> listObj = new LinkedList<>();
       if (requiredClass.equals(Customer.class)) {
           Customer customer = /*...*/
           listObj.add((T)customer);
       }
       return listObj;
}

次に、次のように呼び出すことができます

LinkedList<Customer> custList = getListObjectWithConditionInXMLFile(Customer.class);
于 2013-09-06T17:08:03.087 に答える