发新话题
打印

请教如何在DWT中使用WIndowsTime控件?

本主题由 yidabu 于 2008-6-18 13:45 置顶
请教虾米们,一直想用D语言做个小软件来学习D,现在在windows time这里卡住了,我一直用DWT来实现软件界面,但是现在想使用类似windows time的功能,简单点说就是定时器控件,我在tango和dwt中都没找到,于是自己想写一个,但是一直不成功,所以想请教大家DWT是否已经集成windows time控件了?或者看看我写的控件哪里有问题,谢谢了
代码:
import dwt.DWT;
import dwt.widgets.Control;
import dwt.internal.win32.OS;
import dwt.widgets.Composite;
import dwt.dwthelper.utils;

public interface TWinTimeEvent{
        public void wmTimer(int wParam, int lParam);
};

class TWinTime : Control{
        TWinTimeEvent wte;
        private static /+const+/ WNDPROC ProgressBarProc;
        static const TCHAR[] ProgressBarClass = OS.PROGRESS_CLASS;
       
        public this(Composite parent){
                super(parent,DWT.BORDER);
                setSize(10,10);
        }
        public void startTimer(int TimeLong,TWinTimeEvent lwte){
                if (lwte is null) return ;
                wte=lwte;
                OS.SetTimer(handle,100,TimeLong,null);
        }

        public void stopTimer(){
                OS.KillTimer(handle,100);
        }

        override char[] windowClass () {
                return TCHARsToStr( ProgressBarClass );
        }

        override int windowProc () {
                return cast(int) ProgressBarProc;
        }
       
        override LRESULT WM_TIMER (int wParam, int lParam){
                LRESULT result = super.WM_TIMER (wParam, lParam);
                if (result !is null) return result;
                if ((wParam is 100) && (wte !is null)) {
                        wte.wmTimer(wParam,lParam);
                }
                return result;
        }
};
大家可以试一下这个控件,虽然定时器工作了,但是显示部分搞不定。

TOP

可以发到  dwt 新闻组问问,timer我没有用过。

TOP

完成了基本的功能,哪位大虾要是有更好的代码或者可以改进的希望贴出来大家一起进步。呵呵
module WindowsTime;

import dwt.DWT;
import dwt.internal.win32.OS;
import dwt.widgets.Composite;
import dwt.widgets.Control;

public interface TWinTimeEvent{
        public void wmTimer(int wParam, int lParam);
};

class TWinTime : Control{
        alias Control.computeSize computeSize;
    alias Control.windowProc windowProc;

    static const int TIMER_ID = 100;
    private static /+const+/ WNDPROC WinTimeProc;
    static const TCHAR[] WinTimeClass = OS.PROGRESS_CLASS;
        TWinTimeEvent wte;

    private static bool static_this_completed = false;
    private static void static_this() {
        if( static_this_completed ){
            return;
        }
        synchronized {
            if( static_this_completed ){
                return;
            }
            WNDCLASS lpWndClass;
            OS.GetClassInfo (null, WinTimeClass.ptr, &lpWndClass);
            WinTimeProc = lpWndClass.lpfnWndProc;
            
            auto hInstance = OS.GetModuleHandle (null);
            auto hHeap = OS.GetProcessHeap ();
            lpWndClass.hInstance = hInstance;
            lpWndClass.style &= ~OS.CS_GLOBALCLASS;
            lpWndClass.style |= OS.CS_DBLCLKS;
            int byteCount = (WinTimeClass.length+1) * TCHAR.sizeof;
            TCHAR* lpszClassName = cast(TCHAR*) OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount);
            OS.MoveMemory (lpszClassName, WinTimeClass.ptr, byteCount);
            lpWndClass.lpszClassName = lpszClassName;
            OS.RegisterClass (&lpWndClass);
            OS.HeapFree (hHeap, 0, lpszClassName);
            static_this_completed = true;
        }
    }
       
        public this (Composite parent, int style) {
                static_this();
                super (parent,style);
                setBounds(0,0,0,0);
                setVisible(false);
        }

        override int callWindowProc (HWND hwnd, int msg, int wParam, int lParam) {
                if (handle is null) return 0;
                return OS.CallWindowProc (WinTimeProc, hwnd, msg, wParam, lParam);
        }

        override void releaseWidget () {
                super.releaseWidget ();
        }

        override char[] windowClass () {
                return TCHARsToStr( WinTimeClass );
        }

        override int windowProc () {
                return cast(int) WinTimeProc;
        }

        override LRESULT WM_TIMER (int wParam, int lParam) {
                LRESULT result = super.WM_TIMER (wParam, lParam);
                if (result !is null) return result;
                if (wte !is null){
                        wte.wmTimer(wParam,lParam);
                }
                return result;
        }

        public void startTimer(int TimeLong,TWinTimeEvent lwte){
                if (lwte is null) return ;
                wte=lwte;
                OS.SetTimer(handle,TIMER_ID,TimeLong,null);
        }

        public void stopTimer(){
                OS.KillTimer(handle,TIMER_ID);
        }
};

TOP

dwt中的多线程机制和awt/swing中有些不同:

Display对象中负责调用其他线程的方法有以下3种:

  ● asyncExec(Runnable runnable):异步启动新的线程。所谓异步就是,UI线程不会等待runnable对象执行结束后再继续进行,就是说UI线程可以和runnable对象所在的线程同时运行。

  ● syncExec(Runnable runnable):同步启动新的线程。所谓同步就是,UI线程会等待runnable对象执行结束后才会继续进行,当runnable对象是耗时大的线程时,尽量不要采用此种方式。另外,对于该种方式创建的线程可通过getSyncThread()方法获得线程对象。

  ● timerExec(int milliseconds,Runnable runnable):指定一段时间再启动新的线程。用此方法创建的线程,将会在指定的时间后再启动线程。当然用此方法创建的线程启动后,与UI线程是异步的。如果指定的时间为负数,将不会按时启动线程。

另外Display对象中,与UI线程相关的方法如下所示:

  ● 获得当前的UI线程对象的方法:getThread(),返回Thread对象。

  ● 使UI线程处于休眠状态:sleep()。

  ● 唤醒UI线程:wake()。
  
  display.timerExec(int milliseconds,Runnable runnable) 就相当于一个定时器, 为什么不用呢?

TOP

发新话题