Oberon space

General Category => Общий раздел => Тема начата: ilovb от Октябрь 31, 2012, 10:15:55 am

Название: [CP] Как выделить память под untagged?
Отправлено: ilovb от Октябрь 31, 2012, 10:15:55 am
Никак не соображу. Вот есть у меня:
PtrWSTR* = POINTER TO ARRAY [untagged] OF CHAR;
...
name: WinApi.PtrWSTR;
Как под него правильно выделить память?
Через WinApi?

Я пробовал просто пустую строку присваивать:
name := '';Но потом у BB башню сносит, т.к. я этот name передаю в винапишную функцию, которая пишет строку по этому адресу... и видимо портит память.

Сделал так:
name := '                                                                                                                     ';Проблема исчезла, но не пойму что делает BB в этом случае.

Вот на всякий случай тестовый код:
MODULE SmartTest;
    IMPORT  Log := StdLog,  WinApi, SYSTEM;
   
    PROCEDURE Test1*;
        VAR
            res: WinApi.HWND;
            format: INTEGER;
            name: WinApi.PtrWSTR;
            cchMaxCount: INTEGER;
            i, j: INTEGER;
    BEGIN Log.Clear;
       
        cchMaxCount := 20;
       
        res := WinApi.GetClipboardOwner();
        Log.Int(res); Log.Ln;
       
        IF WinApi.OpenClipboard(0) # 0 THEN
           
            name := '                                                                                                                     ';
           
            Log.String("open"); Log.Ln;
           
            format := 0;
            REPEAT
               
                format := WinApi.EnumClipboardFormats(format);
                Log.Int(format);
               
                CASE format OF
                    | WinApi.CF_TEXT:
                        Log.String(" -- CF_TEXT");
                    | WinApi.CF_BITMAP:
                        Log.String(" -- CF_BITMAP");
                    | WinApi.CF_METAFILEPICT:
                        Log.String(" -- CF_METAFILEPICT");
                    | WinApi.CF_SYLK:
                        Log.String(" -- CF_SYLK");
                    | WinApi.CF_DIF:
                        Log.String(" -- CF_DIF");
                    | WinApi.CF_TIFF:
                        Log.String(" -- CF_TIFF");
                    | WinApi.CF_OEMTEXT:
                        Log.String(" -- CF_OEMTEXT");
                    | WinApi.CF_DIB:
                        Log.String(" -- CF_DIB");
                    | WinApi.CF_PALETTE:
                        Log.String(" -- CF_PALETTE");
                    | WinApi.CF_PENDATA:
                        Log.String(" -- CF_PENDATA");
                    | WinApi.CF_RIFF:
                        Log.String(" -- CF_RIFF");
                    | WinApi.CF_WAVE:
                        Log.String(" -- CF_WAVE");
                    | WinApi.CF_UNICODETEXT:
                        Log.String(" -- CF_UNICODETEXT");
                    | WinApi.CF_ENHMETAFILE:
                        Log.String(" -- CF_ENHMETAFILE");
                    | WinApi.CF_HDROP:
                        Log.String(" -- CF_HDROP");
                    | WinApi.CF_LOCALE:
                        Log.String(" -- CF_LOCALE");
                    | WinApi.CF_MAX:
                        Log.String(" -- CF_MAX");
                    | WinApi.CF_OWNERDISPLAY:
                        Log.String(" -- CF_OWNERDISPLAY");
                    | WinApi.CF_DSPTEXT:
                        Log.String(" -- CF_DSPTEXT");
                    | WinApi.CF_DSPBITMAP:
                        Log.String(" -- CF_DSPBITMAP");
                    | WinApi.CF_DSPMETAFILEPICT:
                        Log.String(" -- CF_DSPMETAFILEPICT");
                    | WinApi.CF_DSPENHMETAFILE:
                        Log.String(" -- CF_DSPENHMETAFILE");
                    | WinApi.CF_PRIVATEFIRST:
                        Log.String(" -- CF_PRIVATEFIRST");
                    | WinApi.CF_PRIVATELAST:
                        Log.String(" -- CF_PRIVATELAST");
                    | WinApi.CF_GDIOBJFIRST:
                        Log.String(" -- CF_GDIOBJFIRST");
                    | WinApi.CF_GDIOBJLAST:
                        Log.String(" -- CF_GDIOBJLAS");
                ELSE   
                   
                    i := WinApi.GetClipboardFormatNameW(format, name, cchMaxCount);
                   
                    Log.String(" -- ");
                    IF i = 0 THEN
                        Log.String("UNKNOWN");
                    END;
                    j := 0;
                    WHILE i > 0 DO                       
                        Log.Char(name[j]);                   
                        INC(j);
                        DEC(i, 1);
                    END;               
                       
                END;
           
            Log.Ln;
           
            UNTIL format = WinApi.ERROR_SUCCESS;
       
        END;
       
        IF WinApi.CloseClipboard() # 0 THEN
            Log.String("close"); Log.Ln;
        END;
       
    END Test1;
   
BEGIN
END SmartTest.Test1
Название: Re: [CP] Как выделить память под untagged?
Отправлено: Губанов Сергей Юрьевич от Октябрь 31, 2012, 10:55:47 am
На стеке можно.

Объявляешь в процедуре локальную переменную bufferForName: ARRAY 1024 OF CHAR. Далее с помощью SYSTEM получаешь адрес нулевого элемента bufferForName[0] и присваиваешь переменной name: WinApi.PtrWSTR.

На Си-образном языке это выглядело бы так:

name = (WinApi.PtrWSTR)&bufferForName[0];
Название: Re: [CP] Как выделить память под untagged?
Отправлено: ilovb от Октябрь 31, 2012, 11:02:24 am
Спасибо. Я в этом направлении думал, но не было уверенности что это будет правильно работать. В документации на этот счет тишина (или я плохо смотрел)
Название: Re: [CP] Как выделить память под untagged?
Отправлено: Губанов Сергей Юрьевич от Октябрь 31, 2012, 11:03:32 am
На Си-образном языке это выглядело бы так:

name = (WinApi.PtrWSTR)&bufferForName[0];

В Блэкбоксе так:

name := SYSTEM.VAL(WinApi.PtrWSTR, SYSTEM.ADR(bufferForName[0]));
Название: Re: [CP] Как выделить память под untagged?
Отправлено: valexey_u от Октябрь 31, 2012, 11:06:03 am
Замечу, что это возможно только в ББ (а приведенное решение, видимо, будет работать только в ББ под Win, в других не будет). В Компонентном Паскале вообще, это сделать нельзя (там собственно нет даже понятия "untagged").
Название: Re: [CP] Как выделить память под untagged?
Отправлено: Губанов Сергей Юрьевич от Октябрь 31, 2012, 11:11:31 am
будет работать только в ББ под Win
Как бы WinApi тоже не везде есть  :)
Название: Re: [CP] Как выделить память под untagged?
Отправлено: valexey_u от Октябрь 31, 2012, 11:15:24 am
будет работать только в ББ под Win
Как бы WinApi тоже не везде есть  :)
Ну, зато бывает CP под виндой, но без ББ :-)
Название: Re: [CP] Как выделить память под untagged?
Отправлено: ilovb от Октябрь 31, 2012, 06:25:57 pm
name := SYSTEM.VAL(WinApi.PtrWSTR, SYSTEM.ADR(bufferForName[0]));

Еще раз спасибо за помощь. Так все работает без ошибок. Свою задачу я решил.