PureBasic - форум

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Вылетает ошибка памяти при работе с thread


Вылетает ошибка памяти при работе с thread

Сообщений 1 страница 10 из 10

1

Здравствуйте!
Не делал раньше многопотоковых приложений.
Сейчас понадобилось сделать listIconGadget, заполняемый в асинхронном режиме. Зачем? Да потому что строк более 13000 на данный момент и будет больше.
Хотелось бы, что бы программа не зависала при заполнении листикона. Ниже код (упрощенный и урезанный).
Как бы всё работает, так как я хочу. Но если в поле поиска несколько раз туда-сюда повбивать символы, то программа рано или поздно выходит в ошибку. Сейчас на 97 строке, где находится  Event=WaitWindowEvent() ; Но это сейчас так, а в основной программе другая строка и функция.
Подскажите, пожалуйста, как делать безопасные пногопоточные приложения. И что исправить конкретно в моём примере. Галочка "безопасный трид" стоит.

Код:
Enumeration
#win_inddb
#filtr_of_list_of_eep_membd
#panel_gadget_win_indbd_1
#list_of_eep_membd_1
#version_membd_1
#total_in_membd_1
#here_shown_1
EndEnumeration

Structure eep_to_db; Структура для листа загружаемой внутренней БД
  nn_def.l
  code.s
  code2.s
  model.s
  addr.l
  size.l
  type.s
EndStructure
NewList load_list_inddb.eep_to_db ()
For i=1 To 10000
  AddElement (load_list_inddb.eep_to_db ())
  load_list_inddb.eep_to_db ()\nn_def=i
  load_list_inddb.eep_to_db ()\code=RSet(Str(Random(99999999999)), 11, "0")
  load_list_inddb.eep_to_db ()\code2=RSet(Str (Random(999999999999)), 12, "0")
  load_list_inddb.eep_to_db ()\model=RSet(Str (Random(999999999)), 9, "0")
  load_list_inddb.eep_to_db ()\size=Random(32768)
  load_list_inddb.eep_to_db ()\type=Str (Random(4))
Next
db_version_1$="01-02-2022"


Procedure fill_gadget_last_list (gadget_to)
  MeasureIntervalStart()
  timest = ElapsedMilliseconds()
  Shared str_to_seearch$, filtr_a.b, here_shown, load_list_inddb ()
  If str_to_seearch$="Search..."
    str_to_seearch$=""
  EndIf
  ResetList (load_list_inddb ())
  ClearGadgetItems(gadget_to)
  i_lli=1; счётчик показанных прошивок
  HideGadget(gadget_to, 0); изменить параметр на 1 что бы скрыть лист при заполнении (увеличивает скорость заполнения, но не интересно)
  ForEach load_list_inddb()
    If filtr_a=0 Or  (filtr_a.b=%00000001 And load_list_inddb()\type="ARCADIA") Or (filtr_a.b=%00000010 And load_list_inddb()\type="EVO II")
      If str_to_seearch$="" Or FindString(load_list_inddb()\code, str_to_seearch$, 1) Or FindString(load_list_inddb()\code2, str_to_seearch$, 1) Or FindString(ReplaceString(load_list_inddb()\model, " ", ""), UCase(str_to_seearch$), 1)
        code_all$=load_list_inddb()\code
        If load_list_inddb()\code2
          code_all$=code_all$+"/"+load_list_inddb()\code2
        EndIf
        AddGadgetItem(gadget_to, i_lli-1, Str(load_list_inddb()\nn_def)+Chr(10)+load_list_inddb()\model+Chr(10)+code_all$+Chr(10)+Str(load_list_inddb()\size)+Chr(10)+load_list_inddb()\type)
        SetGadgetItemData(gadget_to, i_lli-1, load_list_inddb()\addr)
        i_lli+1
        If IsGadget(here_shown) And i_lli%57=0
          SetGadgetText(here_shown, "Shown: "+Str(i_lli-1))
        EndIf
      EndIf
     EndIf
  Next
  HideGadget(gadget_to, 0)
  If IsGadget(here_shown)
    SetGadgetText(here_shown, "Shown: "+Str(i_lli-1))
  EndIf
  Debug (ElapsedMilliseconds()-timest)
EndProcedure

hWnd_inddb=OpenWindow(#win_inddb,0,0,580,480,"IND Data Base Parser © 2016 KDS Soft", #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
;Gadgets
    y0=32
    StringGadget(#filtr_of_list_of_eep_membd, 5, 4, 130, 18, "")
      SetGadgetText(#filtr_of_list_of_eep_membd, "Search...")
      SetGadgetColor(#filtr_of_list_of_eep_membd, #PB_Gadget_FrontColor, $999999)

    PanelGadget(#panel_gadget_win_indbd_1,1, y0, WindowWidth(#win_inddb)-4, WindowHeight(#win_inddb)-y0)
      AddGadgetItem (#panel_gadget_win_indbd_1, -1, "Main DB 1")
        ListIconGadget(#list_of_eep_membd_1, 3,  5+22, GadgetWidth(#panel_gadget_win_indbd_1)-12, GadgetHeight(#panel_gadget_win_indbd_1)-24-y0, "N", 50, #PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect|#PB_ListIcon_AlwaysShowSelection);|#PB_ListIcon_HeaderDragDrop)
        AddGadgetColumn(#list_of_eep_membd_1, 2, "Model", 135)
        AddGadgetColumn(#list_of_eep_membd_1, 3, "Code", 210)
        AddGadgetColumn(#list_of_eep_membd_1, 4, "Size", 55)
        AddGadgetColumn(#list_of_eep_membd_1, 5, "Type", 80)
;        SetGadgetFont(#list_of_eep_membd, FontID(0))
        GadgetToolTip(#list_of_eep_membd_1, "Double click to select and open in the Sky Prog")
        StringGadget(#version_membd_1, 5, 3, 150, 18, "" , #PB_String_ReadOnly|#PB_String_BorderLess)
        StringGadget(#total_in_membd_1, 5+162, 3, 130, 18, "" , #PB_String_ReadOnly|#PB_String_BorderLess)
        StringGadget(#here_shown_1, 5+162+142, 3, 100, 18, "" , #PB_String_ReadOnly|#PB_String_BorderLess)
;       Изменим цвет стрингаджетов на белый вместо серого
        SetGadgetColor (#version_membd_1, #PB_Gadget_BackColor, $FFFFFF)
        SetGadgetColor (#total_in_membd_1, #PB_Gadget_BackColor, $FFFFFF)
        SetGadgetColor (#here_shown_1, #PB_Gadget_BackColor, $FFFFFF)

win_repeats=0; счётчик циклов окна
thread_tab_1=0;hnd для thread
Repeat ; 
  Event=WaitWindowEvent() ;
  If Event=#WM_KEYDOWN ; Была нажата кнопка
;    If GetGadgetText(#filtr_of_list_of_eep_membd)="Search..."
    If GetActiveGadget()<>#filtr_of_list_of_eep_membd
;      SetGadgetText (#filtr_of_list_of_eep_membd, LCase(Chr(EventwParam())))
      SetActiveGadget(#filtr_of_list_of_eep_membd)
;      SendMessage_(GadgetID(#filtr_of_list_of_eep_membd),#EM_SETSEL,100000000,100000000)
      SetGadgetColor(#filtr_of_list_of_eep_membd, #PB_Gadget_FrontColor, $000000)
;      search_change=1
    EndIf
  EndIf
  If Event = #PB_Event_Gadget; Событие гаджетов
    If EventGadget()=#filtr_of_list_of_eep_membd
      If EventType()=#PB_EventType_Change
        search_change=1
      EndIf
      If EventType()=#PB_EventType_LostFocus
        If GetGadgetText(#filtr_of_list_of_eep_membd)=""
          SetGadgetText(#filtr_of_list_of_eep_membd, "Search...")
          SetGadgetColor(#filtr_of_list_of_eep_membd, #PB_Gadget_FrontColor, $999999)
        EndIf
      EndIf
      If EventType()=#PB_EventType_Focus 
        If GetGadgetText(#filtr_of_list_of_eep_membd)="Search..."
          SetGadgetColor(#filtr_of_list_of_eep_membd, #PB_Gadget_FrontColor, $000000)
          SetGadgetText(#filtr_of_list_of_eep_membd, "")
          EndIf
        EndIf
      EndIf
  EndIf
  If win_repeats=0 Or search_change
    search_change=0
    If thread_tab_1 And IsThread(thread_tab_1)
      KillThread (thread_tab_1)
    EndIf
    str_to_seearch$=GetGadgetText(#filtr_of_list_of_eep_membd)
    filtr_a.b=0
    here_shown=#here_shown_1
    thread_tab_1=CreateThread (@fill_gadget_last_list (), #list_of_eep_membd_1);, load_list_inddb_1())
    SetGadgetText(#version_membd_1, "Database version: "+db_version_1$) ; Показываем версию БД
  EndIf
  win_repeats+1
Until Event=#PB_Event_CloseWindow


0

2

Timon написал(а):

Сейчас понадобилось сделать listIconGadget, заполняемый в асинхронном режиме. Зачем? Да потому что строк более 13000 на данный момент и будет больше.

Миллион строк за секунду.

Код:
#ItemCount = 1000000

#LVSICF_NOINVALIDATEALL = 1
#LVSICF_NOSCROLL = 2 
#LVN_ODCACHEHINT = #LVN_FIRST - 13


Global Dim myItems.s(#ItemCount,1) 
Global Dim CheckFlag(#ItemCount)

Procedure WinCallback(hwnd, msg, wParam, lParam)
  result = #PB_ProcessPureBasicEvents 
  Select msg 
    Case #WM_NOTIFY                             
      *nmh.NMHDR = lParam 
      Select *nmh\code
          
        Case #LVN_ODCACHEHINT 
          result = 0
          
        Case #LVN_ODFINDITEM
          result = -1   
          
        Case #LVN_GETDISPINFO 
          *nmlvd.NMLVDISPINFO = lParam
          *nmlvd\item\mask & (#LVIF_TEXT|#LVIF_STATE);|#LVIF_IMAGE
          *nmlvd\item\stateMask = #LVIS_STATEIMAGEMASK
          *nmlvd\item\pszText = @myItems(*nmlvd\item\iItem,*nmlvd\item\iSubItem)
          
          Select CheckFlag(*nmlvd\item\iItem)
            Case 0
              *nmlvd\item\state = 1<<12               
            Case 1
              *nmlvd\item\state = 2<<12
          EndSelect
          
        Case #NM_CLICK
          *nmlv.NM_LISTVIEW = lParam
          If *nmlv\iSubItem = 0 And *nmlv\iItem >= 0
            CheckFlag(*nmlv\iItem) = CheckFlag(*nmlv\iItem) ! 1
            SendMessage_(GadgetID(0), #LVM_REDRAWITEMS ,*nmlv\iItem,*nmlv\iItem)
          EndIf
          
      EndSelect      
      
  EndSelect 
  ProcedureReturn result 
EndProcedure 

OpenWindow(0, 0, 0, 640, 300, "Virtual ListIconGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
SetWindowCallback(@WinCallback())
ListIconGadget(0,10,10,620,280,"ID",100,#LVS_OWNERDATA|#PB_ListIcon_CheckBoxes| #PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect)
SetGadgetColor(0,#PB_Gadget_BackColor, $E1FEFD) 
SendMessage_(GadgetID(0), #LVM_SETITEMCOUNT, #ItemCount, #LVSICF_NOINVALIDATEALL|#LVSICF_NOSCROLL) 
AddGadgetColumn(0,2,"Name",100) 
For i=0 To #ItemCount 
  myItems(i,0) = Str(i) 
  myItems(i,1) = "Name "+Str(i) 
Next i 


Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow

GUI не поддерживает многопоточность.

0

3

Пётр, спасибо.
Для меня этот код сложноватен для понимания. Я так понял, что заполняется только видимая часть. Далее при прокрутке листикон дозаполняется.
Вариант очень интересный, но нужно тоже додуматься, как интегрировать под мои задачи.

Жаль, что GUI не поддерживает многопоточность.

0

4

Пётр, а зачем этот код?

Код:
          Select CheckFlag(*nmlvd\item\iItem)
            Case 0
              *nmlvd\item\state = 1<<12               
            Case 1
              *nmlvd\item\state = 2<<12
          EndSelect
          
        Case #NM_CLICK
          *nmlv.NM_LISTVIEW = lParam
          If *nmlv\iSubItem = 0 And *nmlv\iItem >= 0
            CheckFlag(*nmlv\iItem) = CheckFlag(*nmlv\iItem) ! 1
            SendMessage_(GadgetID(0), #LVM_REDRAWITEMS ,*nmlv\iItem,*nmlv\iItem)
          EndIf

Без этого тоже вроде как работает...

0

5

Timon написал(а):
Код:
          Select CheckFlag(*nmlvd\item\iItem)
            Case 0
              *nmlvd\item\state = 1<<12               
            Case 1
              *nmlvd\item\state = 2<<12
          EndSelect

Это состояние галочек в списке. Если их нет, то ненужно.

Timon написал(а):
Код:
          Case #NM_CLICK
          *nmlv.NM_LISTVIEW = lParam
          If *nmlv\iSubItem = 0 And *nmlv\iItem >= 0
            CheckFlag(*nmlv\iItem) = CheckFlag(*nmlv\iItem) ! 1
            SendMessage_(GadgetID(0), #LVM_REDRAWITEMS ,*nmlv\iItem,*nmlv\iItem)
          EndIf

Это обработчик клика по галочке.

+1

6

Всё понятно. Ещё раз спасибо!

0

7

Немного доработал, работает на ура. Меня больше всего напрягали тормоза при использовании фильтра (поиска). Но с этим виртуальным листом всё отлично.

Код:
#max_rows=500000

Enumeration
#win_inddb
#filtr_of_list_of_eep_membd
#panel_gadget_win_indbd_1
#list_of_eep_membd_1
#version_membd_1
#total_in_membd_1
#here_shown_1
EndEnumeration

Structure eep_to_db; Структура для листа загружаемой внутренней БД
  nn_def.l
  code.s
  code2.s
  model.s
  addr.l
  size.l
  type.s
EndStructure
NewList load_list_inddb.eep_to_db ()
For i=1 To #max_rows
  AddElement (load_list_inddb.eep_to_db ())
  load_list_inddb.eep_to_db ()\nn_def=i
  load_list_inddb.eep_to_db ()\code=RSet(Str(Random(99999999999)), 11, "0")
  load_list_inddb.eep_to_db ()\code2=RSet(Str (Random(999999999999)), 12, "0")
  load_list_inddb.eep_to_db ()\model=RSet(Str (Random(999999999)), 9, "0")
  load_list_inddb.eep_to_db ()\size=Random(32768)
  load_list_inddb.eep_to_db ()\type=Str (Random(4))
Next


#LVSICF_NOINVALIDATEALL = 1
#LVSICF_NOSCROLL = 2 
#LVN_ODCACHEHINT = #LVN_FIRST - 13
Global Dim myItems.s(#max_rows-1,4) 
Procedure WinCallback(WindowId.l, Message.l, wParam.l, lParam.l)
  result = #PB_ProcessPureBasicEvents 
  Select Message
    Case #WM_NOTIFY                             
    *msg.NMHDR = lParam
      Select *msg\code
        Case #LVN_ODCACHEHINT 
          result = 0
        Case #LVN_ODFINDITEM
          result = -1   
        Case #LVN_GETDISPINFO 
          *nmlvd.NMLVDISPINFO = lParam
          *nmlvd\item\mask & (#LVIF_TEXT|#LVIF_STATE);|#LVIF_IMAGE
          *nmlvd\item\stateMask = #LVIS_STATEIMAGEMASK
          *nmlvd\item\pszText = @myItems(*nmlvd\item\iItem,*nmlvd\item\iSubItem)
      EndSelect      
  EndSelect 
  ProcedureReturn result
EndProcedure 


Procedure fill_dim (str_to_seearch$, filtr_a.b, List load_list_inddb.eep_to_db())
  If str_to_seearch$="Search..."
    str_to_seearch$=""
  EndIf
  ;ClearGadgetItems (#list_of_eep_membd_1)
  SendMessage_(GadgetID(#list_of_eep_membd_1), #LVM_SETITEMCOUNT, 0, #LVSICF_NOINVALIDATEALL|#LVSICF_NOSCROLL)
  ResetList (load_list_inddb ())
  listsize = ListSize(load_list_inddb ())
  i_lli=0
  ForEach load_list_inddb()
    If filtr_a.b=0 Or  (filtr_a.b=%00000001 And load_list_inddb()\type="ARCADIA") Or (filtr_a.b=%00000010 And load_list_inddb()\type="EVO II")
      If str_to_seearch$="" Or FindString(load_list_inddb()\code, str_to_seearch$, 1) Or FindString(load_list_inddb()\code2, str_to_seearch$, 1) Or FindString(ReplaceString(load_list_inddb()\model, " ", ""), UCase(str_to_seearch$), 1)
        code_all$=load_list_inddb()\code
        If load_list_inddb()\code2
          code_all$=code_all$+"/"+load_list_inddb()\code2
        EndIf
        myItems (i_lli, 0)=Str(load_list_inddb()\nn_def)
        myItems (i_lli, 1)=load_list_inddb()\model
        myItems (i_lli, 2)=code_all$
        myItems (i_lli, 3)=Str(load_list_inddb()\size)
        myItems (i_lli, 4)=load_list_inddb()\type
        i_lli+1
      EndIf
    EndIf
  Next
  SendMessage_(GadgetID(#list_of_eep_membd_1), #LVM_SETITEMCOUNT, i_lli, #LVSICF_NOINVALIDATEALL|#LVSICF_NOSCROLL)
 ProcedureReturn i_lli
EndProcedure


hWnd_inddb=OpenWindow(#win_inddb,0,0,580,480,"IND Data Base Parser © 2016 KDS Soft", #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
SetWindowCallback(@WinCallback(), #win_inddb)
;Gadgets
    y0=32
    StringGadget(#filtr_of_list_of_eep_membd, 5, 4, 130, 18, "")
      SetGadgetText(#filtr_of_list_of_eep_membd, "Search...")
      SetGadgetColor(#filtr_of_list_of_eep_membd, #PB_Gadget_FrontColor, $999999)

    PanelGadget(#panel_gadget_win_indbd_1,1, y0, WindowWidth(#win_inddb)-4, WindowHeight(#win_inddb)-y0)
      AddGadgetItem (#panel_gadget_win_indbd_1, -1, "Main DB 1")
        ListIconGadget(#list_of_eep_membd_1, 3,  5+22, GadgetWidth(#panel_gadget_win_indbd_1)-12, GadgetHeight(#panel_gadget_win_indbd_1)-24-y0, "N", 50, #LVS_OWNERDATA|#PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect|#PB_ListIcon_AlwaysShowSelection);|#PB_ListIcon_HeaderDragDrop)
        AddGadgetColumn(#list_of_eep_membd_1, 2, "Model", 135)
        AddGadgetColumn(#list_of_eep_membd_1, 3, "Code", 210)
        AddGadgetColumn(#list_of_eep_membd_1, 4, "Size", 55)
        AddGadgetColumn(#list_of_eep_membd_1, 5, "Type", 80)
;        SetGadgetFont(#list_of_eep_membd, FontID(0))
        GadgetToolTip(#list_of_eep_membd_1, "Double click to select and open in the Sky Prog")
        StringGadget(#version_membd_1, 5, 3, 150, 18, "" , #PB_String_ReadOnly|#PB_String_BorderLess)
        StringGadget(#total_in_membd_1, 5+162, 3, 130, 18, "" , #PB_String_ReadOnly|#PB_String_BorderLess)
        StringGadget(#here_shown_1, 5+162+142, 3, 100, 18, "" , #PB_String_ReadOnly|#PB_String_BorderLess)
;       Изменим цвет стрингаджетов на белый вместо серого
        SetGadgetColor (#version_membd_1, #PB_Gadget_BackColor, $FFFFFF)
        SetGadgetColor (#total_in_membd_1, #PB_Gadget_BackColor, $FFFFFF)
        SetGadgetColor (#here_shown_1, #PB_Gadget_BackColor, $FFFFFF)
    SetGadgetText(#version_membd_1, "Database version: 01-02-2022") ; Показываем версию БД
win_repeats=0; счётчик циклов окна

Repeat ; 
  Event=WaitWindowEvent() ;
  If Event=#WM_KEYDOWN ; Была нажата кнопка
;    If GetGadgetText(#filtr_of_list_of_eep_membd)="Search..."
    If EventwParam()>31 And EventwParam()<>38 And EventwParam()<>40
      If GetActiveGadget()<>#filtr_of_list_of_eep_membd
;        SetGadgetText (#filtr_of_list_of_eep_membd, LCase(Chr(EventwParam())))
        SetActiveGadget(#filtr_of_list_of_eep_membd)
;        SendMessage_(GadgetID(#filtr_of_list_of_eep_membd),#EM_SETSEL,100000000,100000000)
        SetGadgetColor(#filtr_of_list_of_eep_membd, #PB_Gadget_FrontColor, $000000)
;        search_change=1
      EndIf
    ElseIf (EventwParam()=38 Or EventwParam()=40) And GetActiveGadget()<>#list_of_eep_membd_1
      SetActiveGadget (#list_of_eep_membd_1)
    EndIf
  EndIf
  If Event = #PB_Event_Gadget; Событие гаджетов
    If EventGadget()=#filtr_of_list_of_eep_membd
      If EventType()=#PB_EventType_Change
        search_change=1
      EndIf
      If EventType()=#PB_EventType_LostFocus
        If GetGadgetText(#filtr_of_list_of_eep_membd)=""
          SetGadgetText(#filtr_of_list_of_eep_membd, "Search...")
          SetGadgetColor(#filtr_of_list_of_eep_membd, #PB_Gadget_FrontColor, $999999)
        EndIf
      EndIf
      If EventType()=#PB_EventType_Focus 
        If GetGadgetText(#filtr_of_list_of_eep_membd)="Search..."
          SetGadgetColor(#filtr_of_list_of_eep_membd, #PB_Gadget_FrontColor, $000000)
          SetGadgetText(#filtr_of_list_of_eep_membd, "")
          EndIf
        EndIf
      EndIf
  EndIf
  If win_repeats=0 Or search_change
timest = ElapsedMilliseconds()
    search_change=0
    count=fill_dim (GetGadgetText(#filtr_of_list_of_eep_membd), filtr_a.b, load_list_inddb.eep_to_db())
    SetGadgetText(#here_shown_1, "Shown: "+Str(count))
;    SetGadgetItemColor(#list_of_eep_membd_1, -1, #PB_Gadget_FrontColor, $FF0000,  1)
Debug (ElapsedMilliseconds()-timest)
  EndIf
  win_repeats+1
Until Event=#PB_Event_CloseWindow


0

8

Вот только теперь не работает установка цвета

Код:
SetGadgetItemColor(#list_of_eep_membd_1, -1, #PB_Gadget_FrontColor, $FF0000,  1)

А мне текст в некоторых столбцах нужно покрасить в синий цвет, что бы они выглядели как ссылки.
Не подскажете, как покрасить нужные столбцы?
Кстати, работает PureCOLOR_SetColumnColor из библиотеки PureCOLOR. Но если его использовать, то стираются линии между ячейками, что для меня тоже не приемлемо.

0

9

Такой метод должен работать.

Код:
; English forum: http://www.purebasic.fr/english/viewtopic.php?t=6085&highlight=
; Author: ebs (updated for PB4.00 by blbltheworm)
; Date: 07. May 2003
; OS: Windows
; Demo: No


#NM_CUSTOMDRAW = #NM_FIRST - 12 

#CDDS_ITEM = $10000 
#CDDS_SUBITEM = $20000 
#CDDS_PREPAINT = $1 
#CDDS_ITEMPREPAINT = #CDDS_ITEM | #CDDS_PREPAINT 
#CDDS_SUBITEMPREPAINT = #CDDS_SUBITEM | #CDDS_ITEMPREPAINT 
#CDRF_DODEFAULT = $0 
#CDRF_NEWFONT = $2 
#CDRF_NOTIFYITEMDRAW = $20 
#CDRF_NOTIFYSUBITEMDRAW = $20 

Global ListGadget.l 

; window callback routine to color listview rows 
Declare.l NotifyCallback(WindowID.l, Message.l, wParam.l, lParam.l) 

; load fonts 
Global FontReg.l, FontBold.l 
FontReg = LoadFont(1, "Tahoma", 9) 
FontBold = LoadFont(2, "Tahoma", 9, #PB_Font_Bold) 

hwnd.l = OpenWindow(0, 0, 0, 356, 197, "Color List View Rows", #PB_Window_ScreenCentered | #PB_Window_SystemMenu) 
CreateGadgetList(hwnd) 

; create list with seven columns 
ListGadget = ListIconGadget(1, 10, 10, 336, 177,"", 70, #PB_ListIcon_GridLines | #LVS_NOSORTHEADER) 
AddGadgetColumn(1, 1, "Sun", 35) 
AddGadgetColumn(1, 2, "Mon", 35) 
AddGadgetColumn(1, 3, "Tue", 35) 
AddGadgetColumn(1, 4, "Wed", 35) 
AddGadgetColumn(1, 5, "Thu", 35) 
AddGadgetColumn(1, 6, " Fri", 35) 
AddGadgetColumn(1, 7, "Sat", 35) 

; add some rows 
AddGadgetItem(1, -1, "  9:00 am" + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX") 
AddGadgetItem(1, -1, "  9:30 am" + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX") 
AddGadgetItem(1, -1, "10:00 am" + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX") 
AddGadgetItem(1, -1, "10:30 am" + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX") 
AddGadgetItem(1, -1, "11:00 am" + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX") 
AddGadgetItem(1, -1, "11:30 am" + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX") 
AddGadgetItem(1, -1, "12:00 pm" + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX") 
AddGadgetItem(1, -1, "12:30 pm" + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX") 
AddGadgetItem(1, -1, "  1:00 pm" + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX") 
AddGadgetItem(1, -1, "  1:30 pm" + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX") 
AddGadgetItem(1, -1, "  2:00 pm" + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX") 
AddGadgetItem(1, -1, "  2:30 pm" + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX") 
AddGadgetItem(1, -1, "  3:00 pm" + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX") 
AddGadgetItem(1, -1, "  3:30 pm" + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX") 
AddGadgetItem(1, -1, "  4:00 pm" + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX") 
AddGadgetItem(1, -1, "  4:30 pm" + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX") 
AddGadgetItem(1, -1, "  5:00 pm" + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX") 

; set callback routine 
SetWindowCallback(@NotifyCallback()) 

Repeat 
Until WaitWindowEvent()=#PB_Event_CloseWindow 

End 

; window callback routine to color listview rows 
Procedure.l NotifyCallback(WindowID.l, Message.l, wParam.l, lParam.l) 
  ; process NOTIFY message only 
  If Message = #WM_NOTIFY 
    ; set stucture pointer 
    *LVCDHeader.NMLVCUSTOMDRAW = lParam 
    ; CUSTOMDRAW message from desired gadget? 
    If *LVCDHeader\nmcd\hdr\hWndFrom = ListGadget And *LVCDHeader\nmcd\hdr\code = #NM_CUSTOMDRAW 
      Select *LVCDHeader\nmcd\dwDrawStage 
        Case #CDDS_PREPAINT 
          ProcedureReturn #CDRF_NOTIFYITEMDRAW 
        Case #CDDS_ITEMPREPAINT 
          ProcedureReturn #CDRF_NOTIFYSUBITEMDRAW 
        Case #CDDS_SUBITEMPREPAINT 
          ; simple example - change background colors every other row 
          ;                  change text colors every other row, only in column 3 
          ;                  text in first column is bold 
          Row.l = *LVCDHeader\nmcd\dwItemSpec 
          Col.l = *LVCDHeader\iSubItem 
          If Col = 0 
            SelectObject_(*LVCDHeader\nmcd\hDC, FontBold) 
          Else 
            SelectObject_(*LVCDHeader\nmcd\hDC, FontReg) 
          EndIf 
          If (Row/2) * 2 = Row 
            *LVCDHeader\clrTextBk = RGB(255, 255, 223) 
            If Col = 3 
              *LVCDHeader\clrText = RGB(255, 0, 0) 
            EndIf 
          Else 
            *LVCDHeader\clrTextBk = RGB(208, 208, 176) 
            If Col = 3 
              *LVCDHeader\clrText = RGB(0, 0, 255) 
            EndIf 
          EndIf 
          ProcedureReturn #CDRF_NEWFONT 
      EndSelect 
    EndIf 
  Else 
    ProcedureReturn #PB_ProcessPureBasicEvents 
  EndIf 
EndProcedure 

0

10

Пётр, спасибо.
Встроил, работает.

0


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Вылетает ошибка памяти при работе с thread